From f23af3661bc25e38c1df49dad0d493022c563882 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Fri, 8 Sep 2023 07:28:41 -0700 Subject: [PATCH] wip --- package.json | 1 + test/playwright/Renderer.test.ts | 82 ++++++++++++++++++++++++++++++++ test/playwright/tsconfig.json | 3 +- yarn.lock | 12 +++++ 4 files changed, 97 insertions(+), 1 deletion(-) create mode 100644 test/playwright/Renderer.test.ts diff --git a/package.json b/package.json index 8ffd1385..77f223aa 100644 --- a/package.json +++ b/package.json @@ -59,6 +59,7 @@ "vtfeatures": "node bin/extract_vtfeatures.js src/**/*.ts src/*.ts" }, "devDependencies": { + "@lunapaint/png-codec": "^0.2.0", "@playwright/test": "^1.37.1", "@types/chai": "^4.2.22", "@types/debug": "^4.1.7", diff --git a/test/playwright/Renderer.test.ts b/test/playwright/Renderer.test.ts new file mode 100644 index 00000000..90cca908 --- /dev/null +++ b/test/playwright/Renderer.test.ts @@ -0,0 +1,82 @@ +/** + * Copyright (c) 2019 The xterm.js authors. All rights reserved. + * @license MIT + */ + +import { decodePng } from '@lunapaint/png-codec'; +import { test } from '@playwright/test'; +import { ITheme } from 'xterm'; +import { createTestContext, ITestContext, openTerminal, pollFor } from './TestUtils'; + +let ctx: ITestContext; +test.beforeAll(async ({ browser }) => { + ctx = await createTestContext(browser); + await openTerminal(ctx); +}); +test.afterAll(async () => await ctx.page.close()); + +test.describe('WebGL Renderer Integration Tests', async () => { + // itWebgl('dispose removes renderer canvases', async function(): Promise { + // await setupBrowser(); + // assert.equal(await page.evaluate(`document.querySelectorAll('.xterm canvas').length`), 2); + // await page.evaluate(`addon.dispose()`); + // assert.equal(await page.evaluate(`document.querySelectorAll('.xterm canvas').length`), 0); + // await browser.close(); + // }); + + test.describe.only('colors', () => { + test('foreground 0-15', async () => { + const theme: ITheme = { + black: '#010203', + red: '#040506', + green: '#070809', + yellow: '#0a0b0c', + blue: '#0d0e0f', + magenta: '#101112', + cyan: '#131415', + white: '#161718' + }; + await ctx.page.evaluate(`window.term.options.theme = ${JSON.stringify(theme)};`); + await ctx.proxy.write(`\x1b[30m█\x1b[31m█\x1b[32m█\x1b[33m█\x1b[34m█\x1b[35m█\x1b[36m█\x1b[37m█`); + await pollFor(ctx.page, () => getCellColor(1, 1), [1, 2, 3, 255]); + await pollFor(ctx.page, () => getCellColor(2, 1), [4, 5, 6, 255]); + await pollFor(ctx.page, () => getCellColor(3, 1), [7, 8, 9, 255]); + await pollFor(ctx.page, () => getCellColor(4, 1), [10, 11, 12, 255]); + await pollFor(ctx.page, () => getCellColor(5, 1), [13, 14, 15, 255]); + await pollFor(ctx.page, () => getCellColor(6, 1), [16, 17, 18, 255]); + await pollFor(ctx.page, () => getCellColor(7, 1), [19, 20, 21, 255]); + await pollFor(ctx.page, () => getCellColor(8, 1), [22, 23, 24, 255]); + }); + }); +}); + +async function getCellColor(col: number, row: number): Promise { + const buffer = await ctx.page.locator('#terminal-container .xterm-rows').screenshot({ path: 'ss.png' }); + const decoded = (await decodePng(buffer)).image; + const cellSize = { + width: decoded.width / await ctx.proxy.cols, + height: decoded.height / await ctx.proxy.rows, + }; + console.log('buffer', buffer); + console.log('decoded', decoded); + console.log('cellSize', cellSize); + const x = 1; //Math.floor((col - 1) + 0.5 * cellSize.width); + const y = 1; //Math.floor((row - 1) + 0.5 * cellSize.height); + const i = y * decoded.width + x; + console.log({ x, y, i }); + console.log('result', Array.from(decoded.data.slice(i, i + 4))); + return Array.from(decoded.data.slice(i, i + 4)); + + await ctx.page.evaluate(` + window.gl = window.term._core._renderService._renderer.value._gl; + window.result = new Uint8Array(4); + window.d = window.term._core._renderService.dimensions; + window.gl.readPixels( + Math.floor((${col - 0.5}) * window.d.device.cell.width), + Math.floor(window.gl.drawingBufferHeight - 1 - (${row - 0.5}) * window.d.device.cell.height), + 1, 1, window.gl.RGBA, window.gl.UNSIGNED_BYTE, window.result + ); + `); + // await page.locator('.header').screenshot({ path: 'screenshot.png' }); + return await ctx.page.evaluate(`Array.from(window.result)`); +} diff --git a/test/playwright/tsconfig.json b/test/playwright/tsconfig.json index 2b5e55fa..aeb31e32 100644 --- a/test/playwright/tsconfig.json +++ b/test/playwright/tsconfig.json @@ -7,7 +7,8 @@ "rootDir": ".", "outDir": "../../out-test/playwright", "types": [ - "../../node_modules/@types/node" + "../../node_modules/@types/node", + "../../node_modules/@lunapaint/png-codec" ], "sourceMap": true, "removeComments": true, diff --git a/yarn.lock b/yarn.lock index 2945d97b..50a4fb84 100644 --- a/yarn.lock +++ b/yarn.lock @@ -326,6 +326,13 @@ "@jridgewell/resolve-uri" "3.1.0" "@jridgewell/sourcemap-codec" "1.4.14" +"@lunapaint/png-codec@^0.2.0": + version "0.2.0" + resolved "https://registry.yarnpkg.com/@lunapaint/png-codec/-/png-codec-0.2.0.tgz#b9fe0a0728889af280c31239b061eb3f8c848816" + integrity sha512-S2Fk8+I27j8ZL585PlEK9hhljZcp6j+JWB5ZHAeePdufJMYHxXD2zlatLRaiy5riXRFqkCi/gong7yP9kSsEZg== + dependencies: + pako "^2.0.4" + "@nodelib/fs.scandir@2.1.5": version "2.1.5" resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" @@ -3002,6 +3009,11 @@ package-hash@^4.0.0: lodash.flattendeep "^4.4.0" release-zalgo "^1.0.0" +pako@^2.0.4: + version "2.1.0" + resolved "https://registry.yarnpkg.com/pako/-/pako-2.1.0.tgz#266cc37f98c7d883545d11335c00fbd4062c9a86" + integrity sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug== + parent-module@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2"