mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Get terminal tests to pass again
Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
parent
7971755e18
commit
c658a0b0da
@ -20,6 +20,5 @@ export const testUsingFakeTime = (dateTime = "2015-10-21T07:28:00Z") => {
|
|||||||
usingFakeTime = true;
|
usingFakeTime = true;
|
||||||
|
|
||||||
jest.useFakeTimers();
|
jest.useFakeTimers();
|
||||||
|
|
||||||
jest.setSystemTime(new Date(dateTime));
|
jest.setSystemTime(new Date(dateTime));
|
||||||
};
|
};
|
||||||
|
|||||||
@ -6,6 +6,44 @@ exports[`test for opening terminal tab within cluster frame when new terminal ta
|
|||||||
<div
|
<div
|
||||||
id="terminal-init"
|
id="terminal-init"
|
||||||
/>
|
/>
|
||||||
|
<div
|
||||||
|
class="Animate slide-right Drawer KubeObjectDetails flex column right leave"
|
||||||
|
style="--size: 725px; --enter-duration: 100ms; --leave-duration: 100ms;"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="drawer-wrapper flex column"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="drawer-title flex align-center"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="drawer-title-text flex gaps align-center"
|
||||||
|
>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<i
|
||||||
|
class="Icon material interactive focusable"
|
||||||
|
tabindex="0"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="icon"
|
||||||
|
data-icon-name="close"
|
||||||
|
>
|
||||||
|
close
|
||||||
|
</span>
|
||||||
|
</i>
|
||||||
|
<div>
|
||||||
|
Close
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="drawer-content flex column box grow"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="ResizingAnchor horizontal leading"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
<div
|
<div
|
||||||
class="Notifications flex column align-flex-end"
|
class="Notifications flex column align-flex-end"
|
||||||
/>
|
/>
|
||||||
|
|||||||
@ -18,6 +18,8 @@ import type { ApplicationBuilder } from "../test-utils/application-builder";
|
|||||||
import { setupInitializingApplicationBuilder } from "../test-utils/application-builder";
|
import { setupInitializingApplicationBuilder } from "../test-utils/application-builder";
|
||||||
import type { FindByTextWithMarkup } from "../../test-utils/findByTextWithMarkup";
|
import type { FindByTextWithMarkup } from "../../test-utils/findByTextWithMarkup";
|
||||||
import { findByTextWithMarkupFor } from "../../test-utils/findByTextWithMarkup";
|
import { findByTextWithMarkupFor } from "../../test-utils/findByTextWithMarkup";
|
||||||
|
import terminalStoreInjectable from "../../renderer/components/dock/terminal/store.injectable";
|
||||||
|
import { flushPromises } from "../../common/test-utils/flush-promises";
|
||||||
|
|
||||||
describe("test for opening terminal tab within cluster frame", () => {
|
describe("test for opening terminal tab within cluster frame", () => {
|
||||||
let builder: ApplicationBuilder;
|
let builder: ApplicationBuilder;
|
||||||
@ -113,8 +115,21 @@ describe("test for opening terminal tab within cluster frame", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe("when the next data is sent", () => {
|
describe("when the next data is sent", () => {
|
||||||
beforeEach(() => {
|
beforeEach(async () => {
|
||||||
|
const terminalStore = builder.applicationWindow.only.di.inject(terminalStoreInjectable);
|
||||||
|
const terminalApi = terminalStore.getTerminalApi("terminal");
|
||||||
|
|
||||||
|
assert(terminalApi);
|
||||||
|
|
||||||
|
const waitForData = new Promise<void>(resolve => terminalApi.on("data", (message) => {
|
||||||
|
if (message) {
|
||||||
|
resolve();
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
await flushPromises();
|
||||||
sendData("I am a prompt");
|
sendData("I am a prompt");
|
||||||
|
await waitForData;
|
||||||
});
|
});
|
||||||
|
|
||||||
it("renders the new data", async () => {
|
it("renders the new data", async () => {
|
||||||
|
|||||||
@ -81,9 +81,10 @@ import { runManySyncFor } from "../../common/runnable/run-many-sync-for";
|
|||||||
import type { MemoryHistory } from "history";
|
import type { MemoryHistory } from "history";
|
||||||
import { object } from "../../common/utils";
|
import { object } from "../../common/utils";
|
||||||
import catalogEntityRegistryInjectable from "../../renderer/api/catalog/entity/registry.injectable";
|
import catalogEntityRegistryInjectable from "../../renderer/api/catalog/entity/registry.injectable";
|
||||||
import { testUsingFakeTime } from "../../common/test-utils/use-fake-time";
|
|
||||||
import createVersionDetectorInjectable from "../../main/cluster-detectors/create-version-detector.injectable";
|
import createVersionDetectorInjectable from "../../main/cluster-detectors/create-version-detector.injectable";
|
||||||
import type { VersionDetector } from "../../main/cluster-detectors/version-detector";
|
import type { VersionDetector } from "../../main/cluster-detectors/version-detector";
|
||||||
|
import getElementByIdInjectable from "../../renderer/utils/get-element-by-id.injectable";
|
||||||
|
import { testUsingFakeTime } from "../../common/test-utils/use-fake-time";
|
||||||
|
|
||||||
type Callback = (di: DiContainer) => void | Promise<void>;
|
type Callback = (di: DiContainer) => void | Promise<void>;
|
||||||
|
|
||||||
@ -237,8 +238,8 @@ export const setupInitializingApplicationBuilder = (init: (builder: ApplicationB
|
|||||||
|
|
||||||
const createElectronWindowFake: CreateElectronWindow = (configuration) => {
|
const createElectronWindowFake: CreateElectronWindow = (configuration) => {
|
||||||
const windowId = configuration.id;
|
const windowId = configuration.id;
|
||||||
|
|
||||||
const windowDi = getRendererDi({ doGeneralOverrides: true });
|
const windowDi = getRendererDi({ doGeneralOverrides: true });
|
||||||
|
let rendered: RenderResult;
|
||||||
|
|
||||||
overrideForWindow(windowDi, windowId);
|
overrideForWindow(windowDi, windowId);
|
||||||
overrideFsWithFakes(windowDi);
|
overrideFsWithFakes(windowDi);
|
||||||
@ -258,7 +259,15 @@ export const setupInitializingApplicationBuilder = (init: (builder: ApplicationB
|
|||||||
return computed(() => [...rendererExtensionState.values()]);
|
return computed(() => [...rendererExtensionState.values()]);
|
||||||
});
|
});
|
||||||
|
|
||||||
let rendered: RenderResult;
|
windowDi.override(getElementByIdInjectable, () => (id) => {
|
||||||
|
const elem = rendered?.container.querySelector(`#${id}`);
|
||||||
|
|
||||||
|
if (!elem) {
|
||||||
|
throw new Error(`Missing #${id} in DOM`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return elem;
|
||||||
|
});
|
||||||
|
|
||||||
windowHelpers.set(windowId, { di: windowDi, getRendered: () => rendered });
|
windowHelpers.set(windowId, { di: windowDi, getRendered: () => rendered });
|
||||||
|
|
||||||
@ -357,7 +366,7 @@ export const setupInitializingApplicationBuilder = (init: (builder: ApplicationB
|
|||||||
windowDi.override(currentLocationInjectable, () => ({
|
windowDi.override(currentLocationInjectable, () => ({
|
||||||
hostname: "localhost",
|
hostname: "localhost",
|
||||||
port: `${mainDi.inject(lensProxyPortInjectable).get()}`,
|
port: `${mainDi.inject(lensProxyPortInjectable).get()}`,
|
||||||
protocol: "http",
|
protocol: "https",
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
import waitUntilPortIsUsedInjectable from "../../common/utils/wait-until-port-is-used/wait-until-port-is-used.injectable";
|
import waitUntilPortIsUsedInjectable from "../../common/utils/wait-until-port-is-used/wait-until-port-is-used.injectable";
|
||||||
import type { Cluster } from "../../common/cluster/cluster";
|
import type { Cluster } from "../../common/cluster/cluster";
|
||||||
import type { KubeAuthProxy } from "../kube-auth-proxy/kube-auth-proxy";
|
import type { KubeAuthProxy } from "../kube-auth-proxy/create-kube-auth-proxy.injectable";
|
||||||
import type { ChildProcess } from "child_process";
|
import type { ChildProcess } from "child_process";
|
||||||
import { Kubectl } from "../kubectl/kubectl";
|
import { Kubectl } from "../kubectl/kubectl";
|
||||||
import type { DeepMockProxy } from "jest-mock-extended";
|
import type { DeepMockProxy } from "jest-mock-extended";
|
||||||
|
|||||||
@ -2,7 +2,6 @@
|
|||||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
*/
|
*/
|
||||||
import { apiKubePrefix } from "../common/vars";
|
|
||||||
import type { Cluster } from "../common/cluster/cluster";
|
import type { Cluster } from "../common/cluster/cluster";
|
||||||
import { getInjectable } from "@ogre-tools/injectable";
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
import type { RequestInit } from "node-fetch";
|
import type { RequestInit } from "node-fetch";
|
||||||
@ -23,8 +22,7 @@ const k8sRequestInjectable = getInjectable({
|
|||||||
|
|
||||||
return async (cluster, path, { timeout = 30_000, ...init } = {}) => {
|
return async (cluster, path, { timeout = 30_000, ...init } = {}) => {
|
||||||
const controller = withTimeout(timeout);
|
const controller = withTimeout(timeout);
|
||||||
|
const response = await lensFetch(`/${cluster.id}${path}`, {
|
||||||
const response = await lensFetch(`/${cluster.id}${apiKubePrefix}${path}`, {
|
|
||||||
...init,
|
...init,
|
||||||
signal: controller.signal,
|
signal: controller.signal,
|
||||||
});
|
});
|
||||||
|
|||||||
@ -17,7 +17,7 @@ import type { SetRequired } from "type-fest";
|
|||||||
import type { EmitAppEvent } from "../../common/app-event-bus/emit-event.injectable";
|
import type { EmitAppEvent } from "../../common/app-event-bus/emit-event.injectable";
|
||||||
import type { Logger } from "../../common/logger";
|
import type { Logger } from "../../common/logger";
|
||||||
import type { SelfSignedCert } from "selfsigned";
|
import type { SelfSignedCert } from "selfsigned";
|
||||||
import type { GetClusterForRequest } from "../cluster/get-cluster-for-request.injectable";
|
import type { GetClusterForRequest } from "./get-cluster-for-request.injectable";
|
||||||
|
|
||||||
export type ServerIncomingMessage = SetRequired<http.IncomingMessage, "url" | "method">;
|
export type ServerIncomingMessage = SetRequired<http.IncomingMessage, "url" | "method">;
|
||||||
export type ProxyRequestHandler = (args: ProxyApiRequestArgs) => void | Promise<void>;
|
export type ProxyRequestHandler = (args: ProxyApiRequestArgs) => void | Promise<void>;
|
||||||
|
|||||||
@ -11,17 +11,19 @@ import currentLocationInjectable from "./current-location.injectable";
|
|||||||
import defaultWebsocketApiParamsInjectable from "./default-websocket-api-params.injectable";
|
import defaultWebsocketApiParamsInjectable from "./default-websocket-api-params.injectable";
|
||||||
import type { TerminalApiDependencies, TerminalApiQuery } from "./terminal-api";
|
import type { TerminalApiDependencies, TerminalApiQuery } from "./terminal-api";
|
||||||
import { TerminalApi } from "./terminal-api";
|
import { TerminalApi } from "./terminal-api";
|
||||||
|
import websocketAgentInjectable from "./websocket-agent.injectable";
|
||||||
|
|
||||||
export type CreateTerminalApi = (query: TerminalApiQuery) => TerminalApi;
|
export type CreateTerminalApi = (query: TerminalApiQuery) => TerminalApi;
|
||||||
|
|
||||||
const createTerminalApiInjectable = getInjectable({
|
const createTerminalApiInjectable = getInjectable({
|
||||||
id: "create-terminal-api",
|
id: "create-terminal-api",
|
||||||
instantiate: (di): CreateTerminalApi => {
|
instantiate: (di): CreateTerminalApi => {
|
||||||
const partialDeps = {
|
const partialDeps: Omit<TerminalApiDependencies, "hostedClusterId"> = {
|
||||||
requestShellApiToken: di.inject(requestShellApiTokenInjectable),
|
requestShellApiToken: di.inject(requestShellApiTokenInjectable),
|
||||||
defaultParams: di.inject(defaultWebsocketApiParamsInjectable),
|
defaultParams: di.inject(defaultWebsocketApiParamsInjectable),
|
||||||
logger: di.inject(loggerInjectable),
|
logger: di.inject(loggerInjectable),
|
||||||
currentLocation: di.inject(currentLocationInjectable),
|
currentLocation: di.inject(currentLocationInjectable),
|
||||||
|
websocketAgent: di.inject(websocketAgentInjectable),
|
||||||
};
|
};
|
||||||
|
|
||||||
return (query) => {
|
return (query) => {
|
||||||
@ -29,12 +31,10 @@ const createTerminalApiInjectable = getInjectable({
|
|||||||
|
|
||||||
assert(hostedClusterId, "Can only create Terminal APIs within cluster frames");
|
assert(hostedClusterId, "Can only create Terminal APIs within cluster frames");
|
||||||
|
|
||||||
const deps: TerminalApiDependencies = {
|
return new TerminalApi({
|
||||||
...partialDeps,
|
...partialDeps,
|
||||||
hostedClusterId,
|
hostedClusterId,
|
||||||
};
|
}, query);
|
||||||
|
|
||||||
return new TerminalApi(deps, query);
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@ -13,6 +13,7 @@ import { type TerminalMessage, TerminalChannels } from "../../common/terminal/ch
|
|||||||
import type { RequestShellApiToken } from "../../features/terminal/renderer/request-shell-api-token.injectable";
|
import type { RequestShellApiToken } from "../../features/terminal/renderer/request-shell-api-token.injectable";
|
||||||
import type { CurrentLocation } from "./current-location.injectable";
|
import type { CurrentLocation } from "./current-location.injectable";
|
||||||
import type { ClusterId } from "../../common/cluster-types";
|
import type { ClusterId } from "../../common/cluster-types";
|
||||||
|
import type { CloseEvent, Event, MessageEvent } from "ws";
|
||||||
|
|
||||||
enum TerminalColor {
|
enum TerminalColor {
|
||||||
RED = "\u001b[31m",
|
RED = "\u001b[31m",
|
||||||
@ -127,7 +128,9 @@ export class TerminalApi extends WebSocketApi<TerminalEvents> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected _onMessage({ data, ...evt }: MessageEvent<string>): void {
|
protected _onMessage(event: MessageEvent): void {
|
||||||
|
const data = event.data as string;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const message = JSON.parse(data) as TerminalMessage;
|
const message = JSON.parse(data) as TerminalMessage;
|
||||||
|
|
||||||
@ -138,7 +141,7 @@ export class TerminalApi extends WebSocketApi<TerminalEvents> {
|
|||||||
* don't want this data to survive if the app is closed
|
* don't want this data to survive if the app is closed
|
||||||
*/
|
*/
|
||||||
window.localStorage.setItem(`${this.query.id}:last-data`, message.data);
|
window.localStorage.setItem(`${this.query.id}:last-data`, message.data);
|
||||||
super._onMessage({ data: message.data, ...evt });
|
super._onMessage({ ...event, data: message.data });
|
||||||
break;
|
break;
|
||||||
case TerminalChannels.CONNECTED:
|
case TerminalChannels.CONNECTED:
|
||||||
this.emit("connected");
|
this.emit("connected");
|
||||||
|
|||||||
@ -0,0 +1,12 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { Agent } from "https";
|
||||||
|
import { getGlobalOverride } from "../../common/test-utils/get-global-override";
|
||||||
|
import websocketAgentInjectable from "./websocket-agent.injectable";
|
||||||
|
|
||||||
|
export default getGlobalOverride(websocketAgentInjectable, () => new Agent({
|
||||||
|
rejectUnauthorized: false,
|
||||||
|
}));
|
||||||
20
src/renderer/api/websocket-agent.injectable.ts
Normal file
20
src/renderer/api/websocket-agent.injectable.ts
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
|
import { Agent } from "https";
|
||||||
|
import lensProxyCertificateInjectable from "../../common/certificate/lens-proxy-certificate.injectable";
|
||||||
|
|
||||||
|
const websocketAgentInjectable = getInjectable({
|
||||||
|
id: "websocket-agent",
|
||||||
|
instantiate: (di) => {
|
||||||
|
const lensProxyCertificate = di.inject(lensProxyCertificateInjectable);
|
||||||
|
|
||||||
|
return new Agent({
|
||||||
|
cert: lensProxyCertificate.get().cert,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default websocketAgentInjectable;
|
||||||
@ -9,6 +9,9 @@ import type TypedEventEmitter from "typed-emitter";
|
|||||||
import type { Defaulted } from "../utils";
|
import type { Defaulted } from "../utils";
|
||||||
import type { DefaultWebsocketApiParams } from "./default-websocket-api-params.injectable";
|
import type { DefaultWebsocketApiParams } from "./default-websocket-api-params.injectable";
|
||||||
import type { Logger } from "../../common/logger";
|
import type { Logger } from "../../common/logger";
|
||||||
|
import type { CloseEvent, Event, MessageEvent } from "ws";
|
||||||
|
import { WebSocket } from "ws";
|
||||||
|
import type { Agent } from "https";
|
||||||
|
|
||||||
interface WebsocketApiParams {
|
interface WebsocketApiParams {
|
||||||
/**
|
/**
|
||||||
@ -66,6 +69,7 @@ export interface WebSocketEvents {
|
|||||||
export interface WebSocketApiDependencies {
|
export interface WebSocketApiDependencies {
|
||||||
readonly defaultParams: DefaultWebsocketApiParams;
|
readonly defaultParams: DefaultWebsocketApiParams;
|
||||||
readonly logger: Logger;
|
readonly logger: Logger;
|
||||||
|
readonly websocketAgent: Agent;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class WebSocketApi<Events extends WebSocketEvents> extends (EventEmitter as { new<T>(): TypedEventEmitter<T> })<Events> {
|
export class WebSocketApi<Events extends WebSocketEvents> extends (EventEmitter as { new<T>(): TypedEventEmitter<T> })<Events> {
|
||||||
@ -100,7 +104,9 @@ export class WebSocketApi<Events extends WebSocketEvents> extends (EventEmitter
|
|||||||
this.socket?.close();
|
this.socket?.close();
|
||||||
|
|
||||||
// start new connection
|
// start new connection
|
||||||
this.socket = new WebSocket(url);
|
this.socket = new WebSocket(url, {
|
||||||
|
agent: this.dependencies.websocketAgent,
|
||||||
|
});
|
||||||
this.socket.addEventListener("open", ev => this._onOpen(ev));
|
this.socket.addEventListener("open", ev => this._onOpen(ev));
|
||||||
this.socket.addEventListener("message", ev => this._onMessage(ev));
|
this.socket.addEventListener("message", ev => this._onMessage(ev));
|
||||||
this.socket.addEventListener("error", ev => this._onError(ev));
|
this.socket.addEventListener("error", ev => this._onError(ev));
|
||||||
@ -164,7 +170,9 @@ export class WebSocketApi<Events extends WebSocketEvents> extends (EventEmitter
|
|||||||
this.writeLog("%cOPEN", "color:green;font-weight:bold;", evt);
|
this.writeLog("%cOPEN", "color:green;font-weight:bold;", evt);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected _onMessage({ data }: MessageEvent<string>): void {
|
protected _onMessage(event: MessageEvent): void {
|
||||||
|
const data = event.data as string;
|
||||||
|
|
||||||
(this as TypedEventEmitter<WebSocketEvents>).emit("data", data);
|
(this as TypedEventEmitter<WebSocketEvents>).emit("data", data);
|
||||||
this.writeLog("%cMESSAGE", "color:black;font-weight:bold;", data);
|
this.writeLog("%cMESSAGE", "color:black;font-weight:bold;", data);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,16 +3,19 @@
|
|||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
*/
|
*/
|
||||||
import { getInjectable } from "@ogre-tools/injectable";
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
import assert from "assert";
|
import { memoize } from "lodash";
|
||||||
|
import getElementByIdInjectable from "../../../utils/get-element-by-id.injectable";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* It is necessary to have this a function because in a testing environment the DOM isn't
|
||||||
|
* available until after first render
|
||||||
|
*/
|
||||||
const terminalSpawningPoolInjectable = getInjectable({
|
const terminalSpawningPoolInjectable = getInjectable({
|
||||||
id: "terminal-spawning-pool",
|
id: "terminal-spawning-pool",
|
||||||
instantiate: () => {
|
instantiate: (di) => {
|
||||||
const pool = document.getElementById("terminal-init");
|
const getElementById = di.inject(getElementByIdInjectable);
|
||||||
|
|
||||||
assert(pool, "DOM MUST contain #terminal-init element");
|
return memoize(() => getElementById("terminal-init"));
|
||||||
|
|
||||||
return pool;
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -24,12 +24,12 @@ import { SearchAddon } from "xterm-addon-search";
|
|||||||
import { WebglAddon } from "xterm-addon-webgl";
|
import { WebglAddon } from "xterm-addon-webgl";
|
||||||
|
|
||||||
export interface TerminalDependencies {
|
export interface TerminalDependencies {
|
||||||
readonly spawningPool: HTMLElement;
|
|
||||||
readonly terminalConfig: IComputedValue<TerminalConfig>;
|
readonly terminalConfig: IComputedValue<TerminalConfig>;
|
||||||
readonly terminalCopyOnSelect: IComputedValue<boolean>;
|
readonly terminalCopyOnSelect: IComputedValue<boolean>;
|
||||||
readonly isMac: boolean;
|
readonly isMac: boolean;
|
||||||
readonly xtermColorTheme: IComputedValue<Record<string, string>>;
|
readonly xtermColorTheme: IComputedValue<Record<string, string>>;
|
||||||
readonly logger: Logger;
|
readonly logger: Logger;
|
||||||
|
spawningPool: () => HTMLElement;
|
||||||
openLinkInBrowser: OpenLinkInBrowser;
|
openLinkInBrowser: OpenLinkInBrowser;
|
||||||
createTerminalRenderer: CreateTerminalRenderer;
|
createTerminalRenderer: CreateTerminalRenderer;
|
||||||
}
|
}
|
||||||
@ -73,7 +73,7 @@ export class Terminal {
|
|||||||
const { elem } = this;
|
const { elem } = this;
|
||||||
|
|
||||||
if (elem) {
|
if (elem) {
|
||||||
this.dependencies.spawningPool.appendChild(elem);
|
this.dependencies.spawningPool().appendChild(elem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -106,7 +106,7 @@ export class Terminal {
|
|||||||
this.xterm.loadAddon(new WebLinksAddon());
|
this.xterm.loadAddon(new WebLinksAddon());
|
||||||
this.xterm.loadAddon(new SearchAddon());
|
this.xterm.loadAddon(new SearchAddon());
|
||||||
|
|
||||||
this.xterm.open(this.dependencies.spawningPool);
|
this.xterm.open(this.dependencies.spawningPool());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const webgl = new WebglAddon();
|
const webgl = new WebglAddon();
|
||||||
|
|||||||
21
src/renderer/utils/get-element-by-id.injectable.ts
Normal file
21
src/renderer/utils/get-element-by-id.injectable.ts
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
|
|
||||||
|
const getElementByIdInjectable = getInjectable({
|
||||||
|
id: "get-element-by-id",
|
||||||
|
instantiate: () => (id: string) => {
|
||||||
|
const elem = document.getElementById(id);
|
||||||
|
|
||||||
|
if (!elem) {
|
||||||
|
throw new Error(`Missing #${id} in DOM`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return elem;
|
||||||
|
},
|
||||||
|
causesSideEffects: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
export default getElementByIdInjectable;
|
||||||
Loading…
Reference in New Issue
Block a user