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", () => {
|
||||
it("should handle opening lens:// links", async () => {
|
||||
await open("lens://internal/foobar");
|
||||
await open("lens://app/foobar");
|
||||
|
||||
await Promise.all([
|
||||
utils.waitForLogsToContain(app, "main", "No handler", "lens://internal/foobar"),
|
||||
utils.waitForLogsToContain(app, "renderer", "No handler", "lens://internal/foobar"),
|
||||
]);
|
||||
await utils.waitForLogsToContain(app, {
|
||||
main: ["No handler", "lens://app/foobar"],
|
||||
renderer: ["No handler", "lens://app/foobar"],
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@ -3,6 +3,7 @@ import * as util from "util";
|
||||
import { exec } from "child_process";
|
||||
import fse from "fs-extra";
|
||||
import path from "path";
|
||||
import { delay } from "../../src/common/utils";
|
||||
|
||||
interface AppTestingPaths {
|
||||
testingPath: string,
|
||||
@ -114,7 +115,46 @@ export async function listHelmRepositories(retries = 0): Promise<HelmRepository
|
||||
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
|
||||
@ -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 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> {
|
||||
const notFoundValues = new Set(values);
|
||||
let lastLogLineCount = 0;
|
||||
export async function waitForLogsToContain(app: Application, matches: LogMatches): Promise<void> {
|
||||
const notYetFound = {
|
||||
main: new Set(matches.main ?? []),
|
||||
renderer: new Set(matches.renderer ?? []),
|
||||
};
|
||||
|
||||
while (notFoundValues.size > 0) {
|
||||
// get all the logs (this returns both) and doesn't clear them
|
||||
const curLogs = ((app as any).chromeDriver.getLogs() as string[]);
|
||||
|
||||
// skip the logs already seen
|
||||
const newLogs = curLogs.slice(lastLogLineCount);
|
||||
|
||||
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);
|
||||
for await (const logs of splitLogs(app)) {
|
||||
mainMatch: for (const logPart of notYetFound.main) {
|
||||
for (const logLine of logs.main) {
|
||||
if (logLine.includes(logPart)) {
|
||||
notYetFound.main.delete(logPart);
|
||||
continue mainMatch; // we have found this log part, try the next part
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
export async function delay(timeoutMs = 1000) {
|
||||
if (!timeoutMs) return;
|
||||
await new Promise(resolve => setTimeout(resolve, timeoutMs));
|
||||
/**
|
||||
* Return a promise that will be resolved after at least `timeout` ms have
|
||||
* passed
|
||||
* @param timeout The number of milliseconds before resolving
|
||||
*/
|
||||
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 "./debouncePromise";
|
||||
export * from "./defineGlobal";
|
||||
export * from "./delay";
|
||||
export * from "./getRandId";
|
||||
export * from "./splitArray";
|
||||
export * from "./saveToAppFiles";
|
||||
|
||||
@ -67,7 +67,7 @@ describe("protocol router tests", () => {
|
||||
lpr.addInternalHandler("/", noop);
|
||||
|
||||
try {
|
||||
expect(await lpr.route("lens://internal")).toBeUndefined();
|
||||
expect(await lpr.route("lens://app")).toBeUndefined();
|
||||
} catch (error) {
|
||||
expect(throwIfDefined(error)).not.toThrow();
|
||||
}
|
||||
@ -79,7 +79,7 @@ describe("protocol router tests", () => {
|
||||
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");
|
||||
});
|
||||
|
||||
@ -89,13 +89,13 @@ describe("protocol router tests", () => {
|
||||
lpr.addInternalHandler("/page", () => { called = true; });
|
||||
|
||||
try {
|
||||
expect(await lpr.route("lens://internal/page")).toBeUndefined();
|
||||
expect(await lpr.route("lens://app/page")).toBeUndefined();
|
||||
} catch (error) {
|
||||
expect(throwIfDefined(error)).not.toThrow();
|
||||
}
|
||||
|
||||
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 () => {
|
||||
@ -105,13 +105,13 @@ describe("protocol router tests", () => {
|
||||
lpr.addInternalHandler("/page/:id", params => { called = params.pathname.id; });
|
||||
|
||||
try {
|
||||
expect(await lpr.route("lens://internal/page/foo")).toBeUndefined();
|
||||
expect(await lpr.route("lens://app/page/foo")).toBeUndefined();
|
||||
} catch (error) {
|
||||
expect(throwIfDefined(error)).not.toThrow();
|
||||
}
|
||||
|
||||
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 () => {
|
||||
@ -229,13 +229,13 @@ describe("protocol router tests", () => {
|
||||
lpr.addInternalHandler("/page/bar", () => { called = 4; });
|
||||
|
||||
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) {
|
||||
expect(throwIfDefined(error)).not.toThrow();
|
||||
}
|
||||
|
||||
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 () => {
|
||||
@ -246,12 +246,12 @@ describe("protocol router tests", () => {
|
||||
lpr.addInternalHandler("/page/bar", () => { called = 4; });
|
||||
|
||||
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) {
|
||||
expect(throwIfDefined(error)).not.toThrow();
|
||||
}
|
||||
|
||||
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