From 44a4bd788f83338891265d133a30de915fc65938 Mon Sep 17 00:00:00 2001 From: Leonardo Bressan Motyczka Date: Fri, 18 Oct 2019 14:48:56 -0300 Subject: [PATCH 1/3] Adjust proposeDimensions to behave like resize --- addons/xterm-addon-fit/src/FitAddon.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/addons/xterm-addon-fit/src/FitAddon.ts b/addons/xterm-addon-fit/src/FitAddon.ts index e25a4783..ca7e24b1 100644 --- a/addons/xterm-addon-fit/src/FitAddon.ts +++ b/addons/xterm-addon-fit/src/FitAddon.ts @@ -17,6 +17,9 @@ interface ITerminalDimensions { cols: number; } +const MINIMUM_COLS = 2; +const MINIMUM_ROWS = 1; + export class FitAddon implements ITerminalAddon { private _terminal: Terminal | undefined; @@ -71,8 +74,8 @@ export class FitAddon implements ITerminalAddon { const availableHeight = parentElementHeight - elementPaddingVer; const availableWidth = parentElementWidth - elementPaddingHor - core.viewport.scrollBarWidth; const geometry = { - cols: Math.floor(availableWidth / core._renderService.dimensions.actualCellWidth), - rows: Math.floor(availableHeight / core._renderService.dimensions.actualCellHeight) + cols: Math.max(MINIMUM_COLS, Math.floor(availableWidth / core._renderService.dimensions.actualCellWidth)), + rows: Math.max(MINIMUM_ROWS, Math.floor(availableHeight / core._renderService.dimensions.actualCellHeight)) }; return geometry; } From a92635b22c82eda268b2b555131acb10ca99c506 Mon Sep 17 00:00:00 2001 From: Leonardo Bressan Motyczka Date: Fri, 18 Oct 2019 14:49:09 -0300 Subject: [PATCH 2/3] Introduce FitAddon tests --- addons/xterm-addon-fit/src/FitAddon.api.ts | 116 +++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 addons/xterm-addon-fit/src/FitAddon.api.ts diff --git a/addons/xterm-addon-fit/src/FitAddon.api.ts b/addons/xterm-addon-fit/src/FitAddon.api.ts new file mode 100644 index 00000000..49d274bc --- /dev/null +++ b/addons/xterm-addon-fit/src/FitAddon.api.ts @@ -0,0 +1,116 @@ +/** + * Copyright (c) 2019 The xterm.js authors. All rights reserved. + * @license MIT + */ + +import * as puppeteer from 'puppeteer'; +import { assert } from 'chai'; +import { ITerminalOptions } from 'xterm'; + +const APP = 'http://127.0.0.1:3000/test'; + +let browser: puppeteer.Browser; +let page: puppeteer.Page; +const width = 1024; +const height = 768; + +describe('FitAddon', () => { + before(async function(): Promise { + this.timeout(20000); + browser = await puppeteer.launch({ + headless: process.argv.indexOf('--headless') !== -1, + slowMo: 80, + args: [`--window-size=${width},${height}`, `--no-sandbox`] + }); + page = (await browser.pages())[0]; + await page.setViewport({ width, height }); + }); + + after(async () => { + await browser.close(); + }); + + beforeEach(async function(): Promise { + this.timeout(20000); + await page.goto(APP); + }); + + describe('proposeDimensions', () => { + it('no terminal', async function(): Promise { + await page.evaluate(`window.fit = new FitAddon();`); + assert.equal(await page.evaluate(`window.fit.proposeDimensions()`), undefined); + }); + + it('default', async function(): Promise { + await openTerminal(); + await loadFit(); + assert.deepEqual(await page.evaluate(`window.fit.proposeDimensions()`), { + cols: 87, + rows: 26 + }); + }); + + it('width', async function(): Promise { + await openTerminal(); + await loadFit(1008); + assert.deepEqual(await page.evaluate(`window.fit.proposeDimensions()`), { + cols: 110, + rows: 26 + }); + }); + + it('small', async function(): Promise { + await openTerminal(); + await loadFit(1, 1); + assert.deepEqual(await page.evaluate(`window.fit.proposeDimensions()`), { + cols: 2, + rows: 1 + }); + }); + }); + + describe('fit', () => { + it('default', async function(): Promise { + await openTerminal(); + await loadFit(); + await page.evaluate(`window.fit.fit()`); + assert.equal(await page.evaluate(`window.term.cols`), 87); + assert.equal(await page.evaluate(`window.term.rows`), 26); + }); + + it('width', async function(): Promise { + await openTerminal(); + await loadFit(1008); + await page.evaluate(`window.fit.fit()`); + assert.equal(await page.evaluate(`window.term.cols`), 110); + assert.equal(await page.evaluate(`window.term.rows`), 26); + }); + + it('small', async function(): Promise { + await openTerminal(); + await loadFit(1, 1); + await page.evaluate(`window.fit.fit()`); + assert.equal(await page.evaluate(`window.term.cols`), 2); + assert.equal(await page.evaluate(`window.term.rows`), 1); + }); + }); +}); + +async function loadFit(width: number = 800, height: number = 450): Promise { + await page.evaluate(` + window.fit = new FitAddon(); + window.term.loadAddon(window.fit); + document.querySelector('#terminal-container').style.width='${width}px'; + document.querySelector('#terminal-container').style.height='${height}px'; + `); +} + +async function openTerminal(options: ITerminalOptions = {}): Promise { + await page.evaluate(`window.term = new Terminal(${JSON.stringify(options)})`); + await page.evaluate(`window.term.open(document.querySelector('#terminal-container'))`); + if (options.rendererType === 'dom') { + await page.waitForSelector('.xterm-rows'); + } else { + await page.waitForSelector('.xterm-text-layer'); + } +} From f8a62a23e59d8a186b5f7cfc1389b1e3d2a2dccb Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Fri, 18 Oct 2019 11:23:11 -0700 Subject: [PATCH 3/3] Speed tests up by avoiding page loads --- addons/xterm-addon-fit/src/FitAddon.api.ts | 29 ++++++++++++---------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/addons/xterm-addon-fit/src/FitAddon.api.ts b/addons/xterm-addon-fit/src/FitAddon.api.ts index 49d274bc..f9972aef 100644 --- a/addons/xterm-addon-fit/src/FitAddon.api.ts +++ b/addons/xterm-addon-fit/src/FitAddon.api.ts @@ -14,7 +14,7 @@ let page: puppeteer.Page; const width = 1024; const height = 768; -describe('FitAddon', () => { +describe.only('FitAddon', () => { before(async function(): Promise { this.timeout(20000); browser = await puppeteer.launch({ @@ -24,25 +24,25 @@ describe('FitAddon', () => { }); page = (await browser.pages())[0]; await page.setViewport({ width, height }); + await page.goto(APP); + await openTerminal(); }); after(async () => { await browser.close(); }); - beforeEach(async function(): Promise { - this.timeout(20000); - await page.goto(APP); + it('no terminal', async function(): Promise { + await page.evaluate(`window.fit = new FitAddon();`); + assert.equal(await page.evaluate(`window.fit.proposeDimensions()`), undefined); }); describe('proposeDimensions', () => { - it('no terminal', async function(): Promise { - await page.evaluate(`window.fit = new FitAddon();`); - assert.equal(await page.evaluate(`window.fit.proposeDimensions()`), undefined); + afterEach(async () => { + return unloadFit(); }); it('default', async function(): Promise { - await openTerminal(); await loadFit(); assert.deepEqual(await page.evaluate(`window.fit.proposeDimensions()`), { cols: 87, @@ -51,7 +51,6 @@ describe('FitAddon', () => { }); it('width', async function(): Promise { - await openTerminal(); await loadFit(1008); assert.deepEqual(await page.evaluate(`window.fit.proposeDimensions()`), { cols: 110, @@ -60,7 +59,6 @@ describe('FitAddon', () => { }); it('small', async function(): Promise { - await openTerminal(); await loadFit(1, 1); assert.deepEqual(await page.evaluate(`window.fit.proposeDimensions()`), { cols: 2, @@ -70,8 +68,11 @@ describe('FitAddon', () => { }); describe('fit', () => { + afterEach(async () => { + return unloadFit(); + }); + it('default', async function(): Promise { - await openTerminal(); await loadFit(); await page.evaluate(`window.fit.fit()`); assert.equal(await page.evaluate(`window.term.cols`), 87); @@ -79,7 +80,6 @@ describe('FitAddon', () => { }); it('width', async function(): Promise { - await openTerminal(); await loadFit(1008); await page.evaluate(`window.fit.fit()`); assert.equal(await page.evaluate(`window.term.cols`), 110); @@ -87,7 +87,6 @@ describe('FitAddon', () => { }); it('small', async function(): Promise { - await openTerminal(); await loadFit(1, 1); await page.evaluate(`window.fit.fit()`); assert.equal(await page.evaluate(`window.term.cols`), 2); @@ -105,6 +104,10 @@ async function loadFit(width: number = 800, height: number = 450): Promise `); } +async function unloadFit(): Promise { + await page.evaluate(`window.fit.dispose();`); +} + async function openTerminal(options: ITerminalOptions = {}): Promise { await page.evaluate(`window.term = new Terminal(${JSON.stringify(options)})`); await page.evaluate(`window.term.open(document.querySelector('#terminal-container'))`);