Terminals test utils
This package presents a list of functions that you can use to simplify testing terminals' functionality.
Function |
Description |
---|---|
Creates a web terminal |
|
Renders a web terminal with a SOM as default content |
|
Generates a visual representation of the terminal's content |
|
Simulates the action of typing characters in the terminal |
|
Focuses a web terminal |
|
Removes the focus from a web terminal |
|
Sends a key to a web terminal |
|
Moves the cursor to a specified location in the terminal |
|
Selects the specified lines and columns of a web terminal |
|
Emulates the mouse down event |
|
Moves the cursor position with a click |
|
Copies the selected text |
|
Pastes the text into the terminal |
|
Simulates a terminal response |

You can see the terminal in the SDK Documentation Test. The plugin is able to clear the terminal.
spec.js
import { addPlugin } from '@orion/core/test-utils';
import { writeChars, textshot } from '@orion/terminals/test-utils';
import { prepareTerminal } from './prepareTerminal.js';
import terminalPluginPkg from './package.json';
import TerminalPlugin from './TerminalPlugin.js';
test('I see the terminal in the SDK Documentation Test', () => {
const terminal = prepareTerminal('tid');
writeChars(terminal, 'PEPE');
expect(textshot(terminal)).toEqual(['>PEPE█']);
});
test('The plugin is able to clear the terminal', () => {
const terminal = prepareTerminal('tid');
writeChars(terminal, 'PEPE');
const plugin = addPlugin(terminalPluginPkg, TerminalPlugin);
plugin.clear('tid');
expect(textshot(terminal)).toEqual(['>█']);
});
TerminalPlugin.js
export default class TerminalPlugin {
constructor({ dispatchersHelper }) {
this._dispatchersHelper = dispatchersHelper;
}
clear(terminalId) {
this._dispatchersHelper.dispatch('clearTerminal', { terminalId });
}
}
package.json
{
"name": "terminal-plugin",
"version": "1.0.0",
"orion": {
"dispatchersHelper": {
"actionCreators": {
"consumes": {
"@orion/terminals": [
"createTerminal",
"clearTerminal"
]
}
}
}
}
}
prepareTerminal.js
import { createTerminal, renderTerminal, focus } from '@orion/terminals/test-utils';
import terminalPluginPkg from './package.json';
import TerminalPlugin from './TerminalPlugin.js';
export function prepareTerminal(terminalId) {
createTerminal({ terminalId });
const terminal = renderTerminal({ terminalId }).container;
focus(terminal);
return terminal;
}
Installation
This library is packed as a part of the @orion/terminals module. You only need to import like: import { test-utils you need } from @orion/terminals/test-utils on your tests in order to be able to use them.
createTerminal
Creates a terminal for the current test. It does not renders the created terminal.
Usage
createTerminal({ terminalId?: string, maxColumns?: number, viewportHeight?: number }): void
-
terminalId: String [OPTIONAL]
Default "terminal1"; identifier for the new terminal
-
maxColumns: Number [OPTIONAL]
Change the default max columns for testing of the new terminal
-
viewportHeigh: Number [OPTIONAL]
Change the default viewport height in pixels for testing of the new terminal
Returns
Nothing.

Plugins can access to the created terminal.
spec.js
import { addPlugin } from '@orion/core/test-utils';
import { createTerminal } from '@orion/terminals/test-utils';
import terminalPluginPkg from './package.json';
import TerminalPlugin from './TerminalPlugin.js';
test('Plugins can access to the created terminal', () => {
createTerminal({ terminalId: 'tId' });
const plugin = addPlugin(terminalPluginPkg, TerminalPlugin);
plugin.write('tId', 'Hello World');
const text = plugin.getText('tId');
expect(text).toEqual('>Hello World');
});
TerminalPlugin.js
export default class TerminalPlugin {
constructor({ storeHelper, selectorsHelper, dispatchersHelper }) {
this._storeHelper = storeHelper;
this._dispatchersHelper = dispatchersHelper;
this._getTerminalVisibleText = selectorsHelper.make('getTerminalVisibleText');
}
write(terminalId, chars) {
this._dispatchersHelper.dispatch('writeTerminalChars', { terminalId, chars });
}
getText(terminalId) {
const state = this._storeHelper.getState();
return this._getTerminalVisibleText(state, { terminalId });
}
}
package.json
{
"name": "terminal-plugin",
"version": "1.0.0",
"orion": {
"dispatchersHelper": {
"actionCreators": {
"consumes": {
"@orion/terminals": [
"createTerminal",
"writeTerminalChars"
]
}
}
},
"selectorsHelper": {
"selectorFactories": {
"consumes": {
"@orion/terminals": [
"getTerminalVisibleText"
]
}
}
}
}
}
renderTerminal
Renders a web terminal with a SOM as default content.
Usage
renderTerminal(terminalProps: Object): RenderResult
-
terminalProps? Object
The props to be sent to the web terminal.
Returns
RenderResult

The rendered terminal is placed in DOM ready to query.
spec.js
import { createTerminal, renderTerminal } from '@orion/terminals/test-utils';
test('The rendered terminal is placed in DOM ready to query', async () => {
createTerminal({ terminalId: 'tId' });
const terminal = renderTerminal({ terminalId: 'tId' }).container;
expect(terminal).toBeInTheDocument;
});
package.json
{
"name": "terminal-plugin",
"version": "1.0.0",
"orion": {
"dispatchersHelper": {
"actionCreators": {
"consumes": {
"@orion/terminals": [
"createTerminal",
"renderTerminal"
]
}
}
}
}
}
textshot
Generates a visual representation of the terminal's content.
Usage
textShot(terminal: container): [String]
-
terminal Terminal Container
Terminal rendered with terminalTestUtils.renderTerminal.
Returns
-
[String]
It returns the visible content of the terminal which is currently shown at the viewport. Each item of the array represents a line of the terminal's content.

Textshot returns a prettyprint of the visible contents of the terminal by line.
spec.js
import { addPlugin } from '@orion/core/test-utils';
import { createTerminal, renderTerminal, textshot } from '@orion/terminals/test-utils';
import terminalPluginPkg from './package.json';
import TerminalPlugin from './TerminalPlugin.js';
test('Textshot returns a prettyprint of the visible contents of the terminal by line', () => {
createTerminal({ terminalId: 'tId', viewportHeight: 20 });
const terminal = renderTerminal({ terminalId: 'tId' }).container;
const plugin = addPlugin(terminalPluginPkg, TerminalPlugin);
plugin.write('tId', 'Hello\nWorld');
expect(textshot(terminal)).toEqual(['>Hello', 'World']);
});
TerminalPlugin.js
export default class TerminalPlugin {
constructor({ storeHelper, selectorsHelper, dispatchersHelper }) {
this._storeHelper = storeHelper;
this._dispatchersHelper = dispatchersHelper;
this._getTerminalVisibleText = selectorsHelper.make('getTerminalVisibleText');
}
write(terminalId, chars) {
this._dispatchersHelper.dispatch('writeTerminalChars', { terminalId, chars });
}
getText(terminalId) {
const state = this._storeHelper.getState();
return this._getTerminalVisibleText(state, { terminalId });
}
}
package.json
{
"name": "terminal-plugin",
"version": "1.0.0",
"orion": {
"dispatchersHelper": {
"actionCreators": {
"consumes": {
"@orion/terminals": [
"createTerminal",
"writeTerminalChars",
"setTerminalViewport"
]
}
}
},
"selectorsHelper": {
"selectorFactories": {
"consumes": {
"@orion/terminals": [
"getTerminalVisibleText"
]
}
}
}
}
}
Textshot works if the content is the first element and it is not inside a wrapper.
Example
test('textshot works also if the first element is the terminal without any wrapper', () => {
const { container } = renderTerminal();
const terminalWithoutWrapper = getByTestId(container, 'terminal');
focus(terminalWithoutWrapper);
expect(textshot(terminalWithoutWrapper)).toEqual(['>█']);
});
Note: Textshot returns only the visible content of the terminal which is shown at the terminal's viewport.

Textshot returns what is visible at the viewport
spec.js
import { addPlugin } from '@orion/core/test-utils';
import { createTerminal, renderTerminal, textshot } from '@orion/terminals/test-utils';
import terminalPluginPkg from './package.json';
import TerminalPlugin from './TerminalPlugin.js';
test('Textshot returns what is visible at the viewport', () => {
createTerminal({ terminalId: 'tId' });
const terminal = renderTerminal({ terminalId: 'tId' }).container;
const plugin = addPlugin(terminalPluginPkg, TerminalPlugin);
plugin.setViewportHeight('tId', 2);
plugin.write('tId', 'l1\nl2\nl3\nl4\nl5');
expect(textshot(terminal)).not.toEqual(['>l1', 'l2', 'l3', 'l4', 'l5']);
});
TerminalPlugin.js
export default class TerminalPlugin {
constructor({ storeHelper, selectorsHelper, dispatchersHelper }) {
this._dispatchersHelper = dispatchersHelper;
}
write(terminalId, chars) {
this._dispatchersHelper.dispatch('writeTerminalChars', { terminalId, chars });
}
setViewportHeight(terminalId, height) {
this._dispatchersHelper.dispatch('setTerminalViewport', {
terminalId,
viewport: { height },
});
}
}
package.json
{
"name": "terminal-plugin",
"version": "1.0.0",
"orion": {
"dispatchersHelper": {
"actionCreators": {
"consumes": {
"@orion/terminals": [
"createTerminal",
"writeTerminalChars",
"setTerminalViewport"
]
}
}
},
"selectorsHelper": {
"selectorFactories": {
"consumes": {
"@orion/terminals": [
"getTerminalVisibleText"
]
}
}
}
}
}
writeChars
Simulates the action of typing characters in the terminal.
Usage
writeChars(terminal: container, chars: String): void
-
terminal Terminal Container
Terminal rendered with terminalTestUtils.renderTerminal.
-
chars String
The characters to be typed.

Writechars emulates the user writting in the terminal.
spec.js
import { createTerminal, renderTerminal, writeChars, textshot } from '@orion/terminals/test-utils';
test('Writechars emulates the user writting in the terminal', async () => {
createTerminal({ terminalId: 'tId' });
const terminal = renderTerminal({ terminalId: 'tId' }).container;
writeChars(terminal, 'Hello World');
expect(textshot(terminal)).toEqual(['>HELLO WORLD']);
});
focus
Focuses a web terminal.
The terminal's cursor appears when the terminal is focused.
Usage
focus(terminal: Terminal container): void
-
terminal Terminal container
Terminal rendered with terminalTestUtils.renderTerminal.

Cursor appears when the terminal is focused.
spec.js
import {
createTerminal,
renderTerminal,
writeChars,
textshot,
focus,
} from '@orion/terminals/test-utils';
test('Cursor appears when the terminal is focused', async () => {
createTerminal({ terminalId: 'tId' });
const terminal = renderTerminal({ terminalId: 'tId' }).container;
writeChars(terminal, 'Hello World');
focus(terminal);
expect(textshot(terminal)).toEqual(['>HELLO WORLD█']);
});
blur
Removes the focus from a web terminal.
Usage
blur(terminal: Terminal container): void
-
terminal Terminal container
Terminal rendered with terminalTestUtils.renderTerminal.

Cursor disappears when terminal is not focused.
spec.js
import {
createTerminal,
renderTerminal,
writeChars,
textshot,
focus,
blur,
} from '@orion/terminals/test-utils';
test('Cursor disappears when terminal is not focused', async () => {
createTerminal({ terminalId: 'tId' });
const terminal = renderTerminal({ terminalId: 'tId' }).container;
writeChars(terminal, 'Hello World');
focus(terminal);
blur(terminal);
expect(textshot(terminal)).toEqual(['>HELLO WORLD']);
});
sendKey
Sends a key to a web terminal.
Useful information: You can send a combination of keys. For example Shift + Arrow Down is equal to S-ArrowDown.
See also: Key Values
Usage
sendKey(terminal: Terminal container, key: String): void
-
terminal Terminal container
Terminal rendered with terminalTestUtils.renderTerminal.
-
key String
Key to be executed.

sendKey interacts with the terminal.
spec.js
import {
createTerminal,
renderTerminal,
writeChars,
textshot,
focus,
sendKey,
} from '@orion/terminals/test-utils';
test('sendKey interacts with the terminal', async () => {
createTerminal({ terminalId: 'tId' });
const terminal = renderTerminal({ terminalId: 'tId' }).container;
writeChars(terminal, 'HELLO');
focus(terminal);
sendKey(terminal, 'ArrowLeft');
sendKey(terminal, 'ArrowLeft');
sendKey(terminal, 'ArrowLeft');
sendKey(terminal, 'ArrowRight');
expect(textshot(terminal)).toEqual(['>HEL█O']);
});
moveCursor
Moves the cursor to a specified position.
Usage
moveCursor(terminalId: String, to: Object): void
-
terminalId: String [OPTIONAL]
Default "terminal1"; identifier for the new terminal
-
to Object
-
line Number
Line of the to position.
-
column Number
Column of the to position.
-

moveCursor moves the pointer to a specified position in the terminal.
spec.js
import {
createTerminal,
renderTerminal,
moveCursor,
textshot,
focus,
writeChars,
} from '@orion/terminals/test-utils';
test('moveCursor moves the pointer to a specified position in the terminal', async () => {
createTerminal({ terminalId: 'tId' });
const terminal = renderTerminal({ terminalId: 'tId' }).container;
focus(terminal);
writeChars(terminal, ' -> <-');
moveCursor('tId', { to: { line: 1, column: 7 } });
expect(textshot(terminal)).toEqual([`> ->█<-`]);
});
select
Selects the specified lines and columns of a web terminal.
Using the textshot method represents the selection with the following characters:
-
▛: Start of selection.
-
▟: End of selection.
-
▐: The character appears at the beginning of the line if the start and end of the selection are from other lines, meaning that the line containing this character is entirely selected.
-
█: The terminal cursor.
Usage
select(terminal: Terminal container, anchorOffset: Object, focusOffset: Object): void
-
terminal Terminal container
Terminal rendered with terminalTestUtils.renderTerminal.
-
anchorOffset Object
The anchor offset of the selection.
-
line Number
Line of the offset.
-
column Number
Column of the offset.
-
-
focusOffset Object
The focus offset of the selection.
-
line Number
Line of the offset.
-
column Number
Column of the offset.
-

test('Selection is shown in the terminal', () => {
const { container } = createTerminal();
writeChars(container, 'LOREM IPSUM DOLOR');
focus(container);
select(container, { lines: 0, columns: 4 }, { lines: 2, columns: 3 });
expect(textshot(container)).toEqual([`>LOR▛M `, `▐PSUM D`, `▐L▟█`]);
});
mouseDown
Emulates the mouse down event. It returns an object with mouseUp and mouseMove functions.
Note: This method is used by terminalsTestUtils.select and terminalsTestUtils.clickAt. Consider using those methods rather than repeating the same logic of both approaches.
Usage
mouseDown(terminal: Terminal container, downOffset: Object): { mouseUp: Function, mouseMove: Function }
-
terminal Terminal container
Terminal rendered with terminalTestUtils.renderTerminal.
-
downOffset Object
The anchor offset of the selection.
-
line Number
Line of the offset.
-
column Number
Column of the offset.
-
Returns
-
[Object]
-
[mouseUp]
Function that receives an offset to fire the mouse up event.
-
[mouseMove]
Function that receives an offset move the mouse.
-

test('Selection is shown in the terminal', () => {
const { container } = createTerminal();
writeChars(container, 'LOREM IPSUM DOLOR');
focus(container);
select(container, { lines: 0, columns: 4 }, { lines: 2, columns: 3 });
expect(textshot(container)).toEqual([`>LOR▛M `, `▐PSUM D`, `▐L▟█`]);
});
clickAt
Moves the cursor position with a click.
Usage
clickAt(terminalProps: Object, offset: Object): void
-
terminal Terminal container
Terminal rendered with terminalTestUtils.renderTerminal.
-
offset Object
The anchor offset of the selection.
-
line Number
Line of the offset.
-
column Number
Column of the offset.
-

test('moves the cursor position with click', () => {
const terminal = createTerminal();
focus(terminal);
clickAt(terminal, { lines: 1, columns: 4 });
expect(textshot(terminal)).toEqual([`${som}`, ` █`]);
});
copy
Copies the selected text.
Usage
copy(terminal: Terminal container): String
-
terminal Terminal container
Terminal rendered with terminalTestUtils.renderTerminal.
Returns
-
[String]
Returns the selected text.

test('Copy event copies the selected text', () => {
const { container } = renderTerminal();
writeChars(container, 'HELLO WORLD');
focus(container);
select(container, { lines: 0, columns: 4 }, { lines: 1, columns: 5 });
const copiedText = copy(container);
expect(copiedText).toEqual('LO \nWORLD');
});
paste
Pastes the text into the terminal.
Usage
paste(terminal: Terminal container, text: String): void
-
terminal Terminal container
Terminal rendered with terminalTestUtils.renderTerminal.
-
text String
Text to be pasted.

test('Paste event pastes the text in the terminal', () => {
const { container } = renderTerminal();
writeChars(container, 'HELLO WORLD');
focus(container);
paste(container, 'DEV');
expect(textshot(container)).toEqual([`${som}HELLO `, 'WORLDDE', 'V█']);
});
mockResponse
Simulate a terminal response for the specified entry.
Usage
mockResponse({ crypticEntry: String? }): Object
-
configuration Object [OPTIONAL]
Configuration for the mocked response.
-
crypticEntry String [OPTIONAL]
Specific entry to response.
-
Returns
-
[Object]
-
[reply]
Function to mock the response.
-
[clean]
Clean existing mocks.
-
[persist]
Avoid removing the mock after sending a response.
-

test('Mock any entry', async () => {
const terminal = prepareTerminal('t1');
plugin.createHostConnection();
mockResponse().reply({
lineAddress: '49',
Payload: 'RESPONSE',
});
plugin.sendEntry('t1', 'ENTRY');
await waitFor(() => expect(textshot(terminal)).toEqual(['RESPONSE']));
});
test('Mock specific entry', async () => {
const terminal = prepareTerminal('t1');
plugin.createHostConnection();
mockResponse({ crypticEntry: 'REQUEST 1' }).reply({
lineAddress: '49',
Payload: 'RESPONSE 1',
});
mockResponse({ crypticEntry: 'REQUEST 2' }).reply({
lineAddress: '49',
Payload: 'RESPONSE 2',
});
plugin.sendEntry('t1', 'REQUEST 1');
plugin.sendEntry('t1', 'REQUEST 2');
await waitFor(() => expect(textshot(terminal)).toEqual(['RESPONSE 1']));
await waitFor(() => expect(textshot(terminal)).toEqual(['RESPONSE 2']));
});
test('Run code before replying', async () => {
const terminal = prepareTerminal('t1');
plugin.createHostConnection();
mockResponse({ crypticEntry: 'REQUEST 1' }).reply(() => {
// Do something
doSomething();
example();
return {
lineAddress: '49',
Payload: `RESPONSE 1`,
};
});
plugin.sendEntry('t1', 'REQUEST 1');
await waitFor(() => expect(textshot(terminal)).toEqual(['RESPONSE 1']));
});
test('Persist the mock', async () => {
const terminal = prepareTerminal('t1');
plugin.createHostConnection();
mockResponse()
.reply({
lineAddress: '49',
Payload: 'RESPONSE',
})
.persist();
plugin.sendEntry('t1', 'ENTRY');
plugin.sendEntry('t1', 'ENTRY');
await waitFor(() => expect(textshot(terminal)).toEqual(['RESPONSE']));
await waitFor(() => expect(textshot(terminal)).toEqual(['RESPONSE']));
});