mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
fix unit and integration tests
Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
parent
0062395550
commit
f8b36055f5
@ -31,12 +31,12 @@ describe("Lens integration tests", () => {
|
|||||||
|
|
||||||
describe("protocol app start", () => {
|
describe("protocol app start", () => {
|
||||||
it("should handle opening lens:// links", async () => {
|
it("should handle opening lens:// links", async () => {
|
||||||
await open("lens://internal/foobar");
|
await open("lens://app/foobar");
|
||||||
|
|
||||||
await Promise.all([
|
await utils.waitForLogsToContain(app, {
|
||||||
utils.waitForLogsToContain(app, "main", "No handler", "lens://internal/foobar"),
|
main: ["No handler", "lens://app/foobar"],
|
||||||
utils.waitForLogsToContain(app, "renderer", "No handler", "lens://internal/foobar"),
|
renderer: ["No handler", "lens://app/foobar"],
|
||||||
]);
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -3,6 +3,7 @@ import * as util from "util";
|
|||||||
import { exec } from "child_process";
|
import { exec } from "child_process";
|
||||||
import fse from "fs-extra";
|
import fse from "fs-extra";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
|
import { delay } from "../../src/common/utils";
|
||||||
|
|
||||||
interface AppTestingPaths {
|
interface AppTestingPaths {
|
||||||
testingPath: string,
|
testingPath: string,
|
||||||
@ -114,7 +115,46 @@ export async function listHelmRepositories(retries = 0): Promise<HelmRepository
|
|||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
const rendererLogPrefixMatcher = /^\[[0-9]{5}:[0-9]{4}\/[0-9]{6}\.[0-9]{6}:[A-Z]+:CONSOLE\([0-9)]+\)\]/;
|
const rendererLogPrefixMatcher = /^\[[0-9]{5}:[0-9]{4}\/[0-9]{6}\.[0-9]{6}:[A-Z]+:CONSOLE\([0-9)]+\)\]\s"(?<message>.*)", source: http:\/\//;
|
||||||
|
|
||||||
|
export interface LogMatches {
|
||||||
|
renderer?: string[];
|
||||||
|
main?: string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
interface LogLines {
|
||||||
|
renderer: string[];
|
||||||
|
main: string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
async function* splitLogs(app: Application): AsyncGenerator<LogLines, void, void> {
|
||||||
|
let lastLogLineCount = 0;
|
||||||
|
|
||||||
|
for(;;) { // infinite loop
|
||||||
|
const curLogs: string[] = (app as any).chromeDriver.getLogs();
|
||||||
|
const newLogs = curLogs.slice(lastLogLineCount);
|
||||||
|
|
||||||
|
lastLogLineCount = curLogs.length;
|
||||||
|
|
||||||
|
const item: LogLines = {
|
||||||
|
renderer: [],
|
||||||
|
main: [],
|
||||||
|
};
|
||||||
|
|
||||||
|
for (const logLine of newLogs) {
|
||||||
|
const logParts = logLine.match(rendererLogPrefixMatcher);
|
||||||
|
|
||||||
|
if (logParts === null) {
|
||||||
|
item.main.push(logLine);
|
||||||
|
} else {
|
||||||
|
item.renderer.push(logParts.groups.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
yield item;
|
||||||
|
await delay(500); // only delay after the first attempt
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wait for all of `values` to be part of the logs. Does not clear logs. Does
|
* Wait for all of `values` to be part of the logs. Does not clear logs. Does
|
||||||
@ -126,34 +166,33 @@ const rendererLogPrefixMatcher = /^\[[0-9]{5}:[0-9]{4}\/[0-9]{6}\.[0-9]{6}:[A-Z]
|
|||||||
* @param source Whether to wait for renderer or main logs
|
* @param source Whether to wait for renderer or main logs
|
||||||
* @param values The list of strings that should all be contained in the logs
|
* @param values The list of strings that should all be contained in the logs
|
||||||
*/
|
*/
|
||||||
export async function waitForLogsToContain(app: Application, source: "renderer" | "main", ...values: string[]): Promise<void> {
|
export async function waitForLogsToContain(app: Application, matches: LogMatches): Promise<void> {
|
||||||
const notFoundValues = new Set(values);
|
const notYetFound = {
|
||||||
let lastLogLineCount = 0;
|
main: new Set(matches.main ?? []),
|
||||||
|
renderer: new Set(matches.renderer ?? []),
|
||||||
|
};
|
||||||
|
|
||||||
while (notFoundValues.size > 0) {
|
for await (const logs of splitLogs(app)) {
|
||||||
// get all the logs (this returns both) and doesn't clear them
|
mainMatch: for (const logPart of notYetFound.main) {
|
||||||
const curLogs = ((app as any).chromeDriver.getLogs() as string[]);
|
for (const logLine of logs.main) {
|
||||||
|
if (logLine.includes(logPart)) {
|
||||||
// skip the logs already seen
|
notYetFound.main.delete(logPart);
|
||||||
const newLogs = curLogs.slice(lastLogLineCount);
|
continue mainMatch; // we have found this log part, try the next part
|
||||||
|
|
||||||
lastLogLineCount += newLogs.length;
|
|
||||||
|
|
||||||
// filter the logs depending on whether we are waiting for logs from main or renderer
|
|
||||||
const filteredLogs = newLogs.filter(logLine => (source === "main") !== Boolean(logLine.match(rendererLogPrefixMatcher)));
|
|
||||||
|
|
||||||
for (const logLine of filteredLogs) {
|
|
||||||
if (notFoundValues.size === 0) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const value of notFoundValues) {
|
|
||||||
if (logLine.includes(value)) {
|
|
||||||
notFoundValues.delete(value);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
await new Promise(resolve => setTimeout(resolve, 500)); // long poll getting logs
|
rendererMatch: for (const logPart of notYetFound.renderer) {
|
||||||
|
for (const logLine of logs.renderer) {
|
||||||
|
if (logLine.includes(logPart)) {
|
||||||
|
notYetFound.renderer.delete(logPart);
|
||||||
|
continue rendererMatch; // we have found this log part, try the next part
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (notYetFound.main.size === 0 && notYetFound.renderer.size === 0) {
|
||||||
|
return; // we are done, have found all log parts
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,8 @@
|
|||||||
// Create async delay for provided timeout in milliseconds
|
/**
|
||||||
|
* Return a promise that will be resolved after at least `timeout` ms have
|
||||||
export async function delay(timeoutMs = 1000) {
|
* passed
|
||||||
if (!timeoutMs) return;
|
* @param timeout The number of milliseconds before resolving
|
||||||
await new Promise(resolve => setTimeout(resolve, timeoutMs));
|
*/
|
||||||
|
export function delay(timeout = 1000): Promise<void> {
|
||||||
|
return new Promise(resolve => setTimeout(resolve, timeout));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,6 +10,7 @@ export * from "./cloneJson";
|
|||||||
export * from "./delay";
|
export * from "./delay";
|
||||||
export * from "./debouncePromise";
|
export * from "./debouncePromise";
|
||||||
export * from "./defineGlobal";
|
export * from "./defineGlobal";
|
||||||
|
export * from "./delay";
|
||||||
export * from "./getRandId";
|
export * from "./getRandId";
|
||||||
export * from "./splitArray";
|
export * from "./splitArray";
|
||||||
export * from "./saveToAppFiles";
|
export * from "./saveToAppFiles";
|
||||||
|
|||||||
@ -67,7 +67,7 @@ describe("protocol router tests", () => {
|
|||||||
lpr.addInternalHandler("/", noop);
|
lpr.addInternalHandler("/", noop);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
expect(await lpr.route("lens://internal")).toBeUndefined();
|
expect(await lpr.route("lens://app")).toBeUndefined();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
expect(throwIfDefined(error)).not.toThrow();
|
expect(throwIfDefined(error)).not.toThrow();
|
||||||
}
|
}
|
||||||
@ -79,7 +79,7 @@ describe("protocol router tests", () => {
|
|||||||
expect(throwIfDefined(error)).not.toThrow();
|
expect(throwIfDefined(error)).not.toThrow();
|
||||||
}
|
}
|
||||||
|
|
||||||
expect(broadcastMessage).toHaveBeenNthCalledWith(1, ProtocolHandlerInternal, "lens://internal");
|
expect(broadcastMessage).toHaveBeenNthCalledWith(1, ProtocolHandlerInternal, "lens://app");
|
||||||
expect(broadcastMessage).toHaveBeenNthCalledWith(2, ProtocolHandlerExtension, "lens://extension/@mirantis/minikube");
|
expect(broadcastMessage).toHaveBeenNthCalledWith(2, ProtocolHandlerExtension, "lens://extension/@mirantis/minikube");
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -89,13 +89,13 @@ describe("protocol router tests", () => {
|
|||||||
lpr.addInternalHandler("/page", () => { called = true; });
|
lpr.addInternalHandler("/page", () => { called = true; });
|
||||||
|
|
||||||
try {
|
try {
|
||||||
expect(await lpr.route("lens://internal/page")).toBeUndefined();
|
expect(await lpr.route("lens://app/page")).toBeUndefined();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
expect(throwIfDefined(error)).not.toThrow();
|
expect(throwIfDefined(error)).not.toThrow();
|
||||||
}
|
}
|
||||||
|
|
||||||
expect(called).toBe(true);
|
expect(called).toBe(true);
|
||||||
expect(broadcastMessage).toBeCalledWith(ProtocolHandlerInternal, "lens://internal/page");
|
expect(broadcastMessage).toBeCalledWith(ProtocolHandlerInternal, "lens://app/page");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should call most exact handler", async () => {
|
it("should call most exact handler", async () => {
|
||||||
@ -105,13 +105,13 @@ describe("protocol router tests", () => {
|
|||||||
lpr.addInternalHandler("/page/:id", params => { called = params.pathname.id; });
|
lpr.addInternalHandler("/page/:id", params => { called = params.pathname.id; });
|
||||||
|
|
||||||
try {
|
try {
|
||||||
expect(await lpr.route("lens://internal/page/foo")).toBeUndefined();
|
expect(await lpr.route("lens://app/page/foo")).toBeUndefined();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
expect(throwIfDefined(error)).not.toThrow();
|
expect(throwIfDefined(error)).not.toThrow();
|
||||||
}
|
}
|
||||||
|
|
||||||
expect(called).toBe("foo");
|
expect(called).toBe("foo");
|
||||||
expect(broadcastMessage).toBeCalledWith(ProtocolHandlerInternal, "lens://internal/page/foo");
|
expect(broadcastMessage).toBeCalledWith(ProtocolHandlerInternal, "lens://app/page/foo");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should call most exact handler for an extension", async () => {
|
it("should call most exact handler for an extension", async () => {
|
||||||
@ -229,13 +229,13 @@ describe("protocol router tests", () => {
|
|||||||
lpr.addInternalHandler("/page/bar", () => { called = 4; });
|
lpr.addInternalHandler("/page/bar", () => { called = 4; });
|
||||||
|
|
||||||
try {
|
try {
|
||||||
expect(await lpr.route("lens://internal/page/foo/bar/bat")).toBeUndefined();
|
expect(await lpr.route("lens://app/page/foo/bar/bat")).toBeUndefined();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
expect(throwIfDefined(error)).not.toThrow();
|
expect(throwIfDefined(error)).not.toThrow();
|
||||||
}
|
}
|
||||||
|
|
||||||
expect(called).toBe(3);
|
expect(called).toBe(3);
|
||||||
expect(broadcastMessage).toBeCalledWith(ProtocolHandlerInternal, "lens://internal/page/foo/bar/bat");
|
expect(broadcastMessage).toBeCalledWith(ProtocolHandlerInternal, "lens://app/page/foo/bar/bat");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should call most exact handler with 2 found handlers", async () => {
|
it("should call most exact handler with 2 found handlers", async () => {
|
||||||
@ -246,12 +246,12 @@ describe("protocol router tests", () => {
|
|||||||
lpr.addInternalHandler("/page/bar", () => { called = 4; });
|
lpr.addInternalHandler("/page/bar", () => { called = 4; });
|
||||||
|
|
||||||
try {
|
try {
|
||||||
expect(await lpr.route("lens://internal/page/foo/bar/bat")).toBeUndefined();
|
expect(await lpr.route("lens://app/page/foo/bar/bat")).toBeUndefined();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
expect(throwIfDefined(error)).not.toThrow();
|
expect(throwIfDefined(error)).not.toThrow();
|
||||||
}
|
}
|
||||||
|
|
||||||
expect(called).toBe(1);
|
expect(called).toBe(1);
|
||||||
expect(broadcastMessage).toBeCalledWith(ProtocolHandlerInternal, "lens://internal/page/foo/bar/bat");
|
expect(broadcastMessage).toBeCalledWith(ProtocolHandlerInternal, "lens://app/page/foo/bar/bat");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user