whopper 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/dist/browser/index.test.d.ts +2 -0
  2. package/dist/browser/index.test.d.ts.map +1 -0
  3. package/dist/browser/index.test.js +181 -0
  4. package/dist/browser/index.test.js.map +1 -0
  5. package/dist/browser/utils.test.d.ts +2 -0
  6. package/dist/browser/utils.test.d.ts.map +1 -0
  7. package/dist/browser/utils.test.js +33 -0
  8. package/dist/browser/utils.test.js.map +1 -0
  9. package/dist/cli.test.d.ts +2 -0
  10. package/dist/cli.test.d.ts.map +1 -0
  11. package/dist/cli.test.js +52 -0
  12. package/dist/cli.test.js.map +1 -0
  13. package/dist/commands/banner.test.d.ts +2 -0
  14. package/dist/commands/banner.test.d.ts.map +1 -0
  15. package/dist/commands/banner.test.js +24 -0
  16. package/dist/commands/banner.test.js.map +1 -0
  17. package/dist/commands/detect.test.d.ts +2 -0
  18. package/dist/commands/detect.test.d.ts.map +1 -0
  19. package/dist/commands/detect.test.js +194 -0
  20. package/dist/commands/detect.test.js.map +1 -0
  21. package/dist/commands/detect_utils.test.d.ts +2 -0
  22. package/dist/commands/detect_utils.test.d.ts.map +1 -0
  23. package/dist/commands/detect_utils.test.js +449 -0
  24. package/dist/commands/detect_utils.test.js.map +1 -0
  25. package/dist/commands/version.test.d.ts +2 -0
  26. package/dist/commands/version.test.d.ts.map +1 -0
  27. package/dist/commands/version.test.js +27 -0
  28. package/dist/commands/version.test.js.map +1 -0
  29. package/dist/e2e/cli.e2e.test.d.ts +2 -0
  30. package/dist/e2e/cli.e2e.test.d.ts.map +1 -0
  31. package/dist/e2e/cli.e2e.test.js +85 -0
  32. package/dist/e2e/cli.e2e.test.js.map +1 -0
  33. package/dist/logger/index.test.d.ts +2 -0
  34. package/dist/logger/index.test.d.ts.map +1 -0
  35. package/dist/logger/index.test.js +106 -0
  36. package/dist/logger/index.test.js.map +1 -0
  37. package/dist/logger/utils.test.d.ts +2 -0
  38. package/dist/logger/utils.test.d.ts.map +1 -0
  39. package/dist/logger/utils.test.js +20 -0
  40. package/dist/logger/utils.test.js.map +1 -0
  41. package/dist/signatures/signatures.test.d.ts +2 -0
  42. package/dist/signatures/signatures.test.d.ts.map +1 -0
  43. package/dist/signatures/signatures.test.js +128 -0
  44. package/dist/signatures/signatures.test.js.map +1 -0
  45. package/dist/signatures/utils.test.d.ts +2 -0
  46. package/dist/signatures/utils.test.d.ts.map +1 -0
  47. package/dist/signatures/utils.test.js +85 -0
  48. package/dist/signatures/utils.test.js.map +1 -0
  49. package/package.json +1 -1
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.test.d.ts","sourceRoot":"","sources":["../../src/browser/index.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,181 @@
1
+ import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
2
+ import { openPage } from "./index.js";
3
+ // Mock playwright
4
+ vi.mock("playwright", () => {
5
+ const mockPage = {
6
+ on: vi.fn(),
7
+ goto: vi.fn(),
8
+ context: vi.fn(),
9
+ evaluate: vi.fn(),
10
+ close: vi.fn(),
11
+ };
12
+ const mockBrowserContext = {
13
+ newPage: vi.fn(() => Promise.resolve(mockPage)),
14
+ cookies: vi.fn(() => Promise.resolve([])),
15
+ };
16
+ const mockBrowser = {
17
+ newContext: vi.fn(() => Promise.resolve(mockBrowserContext)),
18
+ close: vi.fn(),
19
+ };
20
+ return {
21
+ chromium: {
22
+ launch: vi.fn(() => Promise.resolve(mockBrowser)),
23
+ },
24
+ };
25
+ });
26
+ // Mock logger
27
+ vi.mock("../logger/index.js", () => ({
28
+ logger: {
29
+ debug: vi.fn(),
30
+ info: vi.fn(),
31
+ warn: vi.fn(),
32
+ error: vi.fn(),
33
+ },
34
+ }));
35
+ // Mock sleep to be instant in tests
36
+ vi.mock("./utils.js", () => ({
37
+ sleep: vi.fn(() => Promise.resolve()),
38
+ }));
39
+ import { chromium } from "playwright";
40
+ import { logger } from "../logger/index.js";
41
+ import { sleep } from "./utils.js";
42
+ describe("openPage", () => {
43
+ let mockPage;
44
+ let mockBrowserContext;
45
+ let mockBrowser;
46
+ beforeEach(() => {
47
+ vi.clearAllMocks();
48
+ // Get references to mocked objects
49
+ mockPage = {
50
+ on: vi.fn(),
51
+ goto: vi.fn(() => Promise.resolve()),
52
+ context: vi.fn(),
53
+ evaluate: vi.fn(() => Promise.resolve({})),
54
+ close: vi.fn(),
55
+ };
56
+ mockBrowserContext = {
57
+ newPage: vi.fn(() => Promise.resolve(mockPage)),
58
+ cookies: vi.fn(() => Promise.resolve([])),
59
+ };
60
+ mockBrowser = {
61
+ newContext: vi.fn(() => Promise.resolve(mockBrowserContext)),
62
+ close: vi.fn(),
63
+ };
64
+ mockPage.context.mockReturnValue(mockBrowserContext);
65
+ vi.mocked(chromium.launch).mockResolvedValue(mockBrowser);
66
+ });
67
+ afterEach(() => {
68
+ vi.restoreAllMocks();
69
+ });
70
+ describe("successful page load", () => {
71
+ it("should launch browser with headless mode", async () => {
72
+ await openPage("https://example.com", 10000, []);
73
+ expect(chromium.launch).toHaveBeenCalledWith({ headless: true });
74
+ });
75
+ it("should create browser context with ignoreHTTPSErrors", async () => {
76
+ await openPage("https://example.com", 10000, []);
77
+ expect(mockBrowser.newContext).toHaveBeenCalledWith({
78
+ ignoreHTTPSErrors: true,
79
+ });
80
+ });
81
+ it("should navigate to the specified URL", async () => {
82
+ await openPage("https://example.com", 10000, []);
83
+ expect(mockPage.goto).toHaveBeenCalledWith("https://example.com", {
84
+ waitUntil: "networkidle",
85
+ });
86
+ });
87
+ it("should log success message on successful load", async () => {
88
+ mockPage.goto.mockResolvedValue(undefined);
89
+ vi.mocked(sleep).mockImplementation(() => new Promise((resolve) => setTimeout(resolve, 100)));
90
+ await openPage("https://example.com", 10000, []);
91
+ expect(logger.info).toHaveBeenCalledWith("Page loaded successfully");
92
+ });
93
+ it("should return context with expected properties", async () => {
94
+ mockPage.goto.mockResolvedValue(undefined);
95
+ vi.mocked(sleep).mockImplementation(() => new Promise((resolve) => setTimeout(resolve, 100)));
96
+ const result = await openPage("https://example.com", 5000, []);
97
+ expect(result).toHaveProperty("browser");
98
+ expect(result).toHaveProperty("page");
99
+ expect(result).toHaveProperty("responses");
100
+ expect(result).toHaveProperty("javascriptVariables");
101
+ expect(result).toHaveProperty("cookies");
102
+ expect(result).toHaveProperty("timeoutMs", 5000);
103
+ expect(result).toHaveProperty("timeoutOccurred", false);
104
+ });
105
+ });
106
+ describe("timeout handling", () => {
107
+ it("should set timeoutOccurred to true when timeout occurs", async () => {
108
+ // Make goto never resolve, and sleep resolve immediately
109
+ mockPage.goto.mockImplementation(() => new Promise(() => { }));
110
+ vi.mocked(sleep).mockResolvedValue(undefined);
111
+ const result = await openPage("https://example.com", 1000, []);
112
+ expect(result.timeoutOccurred).toBe(true);
113
+ expect(logger.warn).toHaveBeenCalledWith(expect.stringContaining("Timeout"));
114
+ });
115
+ });
116
+ describe("error handling", () => {
117
+ it("should log error when page load fails", async () => {
118
+ mockPage.goto.mockRejectedValue(new Error("Connection refused"));
119
+ vi.mocked(sleep).mockImplementation(() => new Promise((resolve) => setTimeout(resolve, 100)));
120
+ await openPage("https://example.com", 10000, []);
121
+ expect(logger.error).toHaveBeenCalledWith(expect.stringContaining("Connection refused"));
122
+ });
123
+ it("should handle cookie/JS extraction failure gracefully", async () => {
124
+ mockPage.goto.mockResolvedValue(undefined);
125
+ mockBrowserContext.cookies.mockRejectedValue(new Error("Context destroyed"));
126
+ vi.mocked(sleep).mockImplementation(() => new Promise((resolve) => setTimeout(resolve, 100)));
127
+ const result = await openPage("https://example.com", 10000, []);
128
+ expect(logger.warn).toHaveBeenCalledWith(expect.stringContaining("Failed to extract cookies"));
129
+ expect(result.cookies).toEqual([]);
130
+ });
131
+ });
132
+ describe("cookie extraction", () => {
133
+ it("should extract cookies from page context", async () => {
134
+ const mockCookies = [
135
+ {
136
+ name: "session",
137
+ value: "abc123",
138
+ domain: "example.com",
139
+ path: "/",
140
+ expires: -1,
141
+ httpOnly: true,
142
+ secure: true,
143
+ sameSite: "Lax",
144
+ },
145
+ ];
146
+ mockPage.goto.mockResolvedValue(undefined);
147
+ mockBrowserContext.cookies.mockResolvedValue(mockCookies);
148
+ vi.mocked(sleep).mockImplementation(() => new Promise((resolve) => setTimeout(resolve, 100)));
149
+ const result = await openPage("https://example.com", 10000, []);
150
+ expect(result.cookies).toEqual([
151
+ {
152
+ name: "session",
153
+ value: "abc123",
154
+ domain: "example.com",
155
+ path: "/",
156
+ expires: -1,
157
+ httpOnly: true,
158
+ secure: true,
159
+ sameSite: "Lax",
160
+ },
161
+ ]);
162
+ });
163
+ });
164
+ describe("javascript variable extraction", () => {
165
+ it("should evaluate javascript variables on page", async () => {
166
+ mockPage.goto.mockResolvedValue(undefined);
167
+ mockPage.evaluate.mockResolvedValue({ jQuery: "3.6.0" });
168
+ vi.mocked(sleep).mockImplementation(() => new Promise((resolve) => setTimeout(resolve, 100)));
169
+ const result = await openPage("https://example.com", 10000, ["jQuery"]);
170
+ expect(mockPage.evaluate).toHaveBeenCalled();
171
+ expect(result.javascriptVariables).toEqual({ jQuery: "3.6.0" });
172
+ });
173
+ });
174
+ describe("response listener", () => {
175
+ it("should register response listener on page", async () => {
176
+ await openPage("https://example.com", 10000, []);
177
+ expect(mockPage.on).toHaveBeenCalledWith("response", expect.any(Function));
178
+ });
179
+ });
180
+ });
181
+ //# sourceMappingURL=index.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.test.js","sourceRoot":"","sources":["../../src/browser/index.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=utils.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.test.d.ts","sourceRoot":"","sources":["../../src/browser/utils.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,33 @@
1
+ import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
2
+ import { sleep } from "./utils.js";
3
+ describe("sleep", () => {
4
+ beforeEach(() => {
5
+ vi.useFakeTimers();
6
+ });
7
+ afterEach(() => {
8
+ vi.useRealTimers();
9
+ });
10
+ it("should resolve after specified milliseconds", async () => {
11
+ const sleepPromise = sleep(1000);
12
+ vi.advanceTimersByTime(1000);
13
+ await expect(sleepPromise).resolves.toBeUndefined();
14
+ });
15
+ it("should not resolve before specified time", async () => {
16
+ let resolved = false;
17
+ sleep(1000).then(() => {
18
+ resolved = true;
19
+ });
20
+ vi.advanceTimersByTime(500);
21
+ await Promise.resolve(); // Flush microtasks
22
+ expect(resolved).toBe(false);
23
+ vi.advanceTimersByTime(500);
24
+ await Promise.resolve(); // Flush microtasks
25
+ expect(resolved).toBe(true);
26
+ });
27
+ it("should handle zero milliseconds", async () => {
28
+ const sleepPromise = sleep(0);
29
+ vi.advanceTimersByTime(0);
30
+ await expect(sleepPromise).resolves.toBeUndefined();
31
+ });
32
+ });
33
+ //# sourceMappingURL=utils.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.test.js","sourceRoot":"","sources":["../../src/browser/utils.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACzE,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAEnC,QAAQ,CAAC,OAAO,EAAE,GAAG,EAAE;IACrB,UAAU,CAAC,GAAG,EAAE;QACd,EAAE,CAAC,aAAa,EAAE,CAAC;IACrB,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACb,EAAE,CAAC,aAAa,EAAE,CAAC;IACrB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6CAA6C,EAAE,KAAK,IAAI,EAAE;QAC3D,MAAM,YAAY,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC;QACjC,EAAE,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC;QAC7B,MAAM,MAAM,CAAC,YAAY,CAAC,CAAC,QAAQ,CAAC,aAAa,EAAE,CAAC;IACtD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0CAA0C,EAAE,KAAK,IAAI,EAAE;QACxD,IAAI,QAAQ,GAAG,KAAK,CAAC;QACrB,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE;YACpB,QAAQ,GAAG,IAAI,CAAC;QAClB,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAC;QAC5B,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,mBAAmB;QAC5C,MAAM,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAE7B,EAAE,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAC;QAC5B,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,mBAAmB;QAC5C,MAAM,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC9B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iCAAiC,EAAE,KAAK,IAAI,EAAE;QAC/C,MAAM,YAAY,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QAC9B,EAAE,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC;QAC1B,MAAM,MAAM,CAAC,YAAY,CAAC,CAAC,QAAQ,CAAC,aAAa,EAAE,CAAC;IACtD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=cli.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.test.d.ts","sourceRoot":"","sources":["../src/cli.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,52 @@
1
+ import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
2
+ import { run, VERSION } from "./cli.js";
3
+ describe("cli", () => {
4
+ let consoleErrorSpy;
5
+ let stdoutWriteSpy;
6
+ let processExitSpy;
7
+ beforeEach(() => {
8
+ consoleErrorSpy = vi.spyOn(console, "error").mockImplementation(() => { });
9
+ stdoutWriteSpy = vi
10
+ .spyOn(process.stdout, "write")
11
+ .mockImplementation(() => true);
12
+ processExitSpy = vi
13
+ .spyOn(process, "exit")
14
+ .mockImplementation(() => undefined);
15
+ });
16
+ afterEach(() => {
17
+ consoleErrorSpy.mockRestore();
18
+ stdoutWriteSpy.mockRestore();
19
+ processExitSpy.mockRestore();
20
+ });
21
+ describe("VERSION", () => {
22
+ it("should be a valid semver string", () => {
23
+ expect(VERSION).toMatch(/^\d+\.\d+\.\d+$/);
24
+ });
25
+ });
26
+ describe("run", () => {
27
+ it("should print banner on startup", () => {
28
+ run(["node", "whopper", "--help"]);
29
+ const output = consoleErrorSpy.mock.calls
30
+ .map((c) => c[0])
31
+ .join("\n");
32
+ expect(output).toContain("Whopper");
33
+ expect(output).toContain(VERSION);
34
+ });
35
+ it("should show help with --help flag", () => {
36
+ run(["node", "whopper", "--help"]);
37
+ const output = stdoutWriteSpy.mock.calls
38
+ .map((c) => String(c[0]))
39
+ .join("");
40
+ expect(output).toContain("Usage:");
41
+ expect(output).toContain("detect");
42
+ });
43
+ it("should show version with --version flag", () => {
44
+ run(["node", "whopper", "--version"]);
45
+ const output = stdoutWriteSpy.mock.calls
46
+ .map((c) => String(c[0]))
47
+ .join("");
48
+ expect(output).toContain(VERSION);
49
+ });
50
+ });
51
+ });
52
+ //# sourceMappingURL=cli.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.test.js","sourceRoot":"","sources":["../src/cli.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=banner.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"banner.test.d.ts","sourceRoot":"","sources":["../../src/commands/banner.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,24 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { banner } from "./banner.js";
3
+ describe("banner", () => {
4
+ it("should return a string containing the version", () => {
5
+ const result = banner("1.0.0");
6
+ expect(result).toContain("1.0.0");
7
+ });
8
+ it("should return a string containing Whopper", () => {
9
+ const result = banner("1.0.0");
10
+ expect(result).toContain("Whopper");
11
+ });
12
+ it("should return ASCII art banner", () => {
13
+ const result = banner("1.0.0");
14
+ // Check for presence of ASCII art characters
15
+ expect(result).toContain("██");
16
+ expect(result).toContain("╔");
17
+ expect(result).toContain("╝");
18
+ });
19
+ it("should include description text", () => {
20
+ const result = banner("1.0.0");
21
+ expect(result).toContain("web technology detection tool");
22
+ });
23
+ });
24
+ //# sourceMappingURL=banner.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"banner.test.js","sourceRoot":"","sources":["../../src/commands/banner.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,QAAQ,CAAC,QAAQ,EAAE,GAAG,EAAE;IACtB,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;QACvD,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;QAC/B,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2CAA2C,EAAE,GAAG,EAAE;QACnD,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;QAC/B,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gCAAgC,EAAE,GAAG,EAAE;QACxC,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;QAC/B,6CAA6C;QAC7C,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QAC/B,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;QAC9B,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;IAChC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iCAAiC,EAAE,GAAG,EAAE;QACzC,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;QAC/B,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,+BAA+B,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=detect.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detect.test.d.ts","sourceRoot":"","sources":["../../src/commands/detect.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,194 @@
1
+ import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
2
+ import { detectCommand } from "./detect.js";
3
+ // Mock dependencies
4
+ vi.mock("../browser/index.js", () => ({
5
+ openPage: vi.fn(),
6
+ }));
7
+ vi.mock("../analyzer/index.js", () => ({
8
+ analyze: vi.fn(),
9
+ }));
10
+ vi.mock("../logger/index.js", () => ({
11
+ logger: {
12
+ debug: vi.fn(),
13
+ info: vi.fn(),
14
+ warn: vi.fn(),
15
+ error: vi.fn(),
16
+ },
17
+ setLogLevel: vi.fn(),
18
+ }));
19
+ vi.mock("./detect_utils.js", () => ({
20
+ makeDetectCommandOutput: vi.fn(),
21
+ printDetectCommandOutputAsJSON: vi.fn(),
22
+ printDetectCommandOutputAsText: vi.fn(),
23
+ }));
24
+ import { openPage } from "../browser/index.js";
25
+ import { analyze } from "../analyzer/index.js";
26
+ import { logger, setLogLevel } from "../logger/index.js";
27
+ import { makeDetectCommandOutput, printDetectCommandOutputAsJSON, printDetectCommandOutputAsText, } from "./detect_utils.js";
28
+ describe("detectCommand", () => {
29
+ let mockContext;
30
+ beforeEach(() => {
31
+ vi.clearAllMocks();
32
+ process.exitCode = undefined;
33
+ mockContext = {
34
+ browser: { close: vi.fn() },
35
+ page: { close: vi.fn() },
36
+ responses: [],
37
+ javascriptVariables: {},
38
+ cookies: [],
39
+ timeoutMs: 10000,
40
+ timeoutOccurred: false,
41
+ };
42
+ vi.mocked(openPage).mockResolvedValue(mockContext);
43
+ vi.mocked(analyze).mockReturnValue([]);
44
+ });
45
+ afterEach(() => {
46
+ vi.restoreAllMocks();
47
+ });
48
+ // Helper to run command
49
+ const runCommand = async (args = []) => {
50
+ const command = detectCommand();
51
+ command.exitOverride(); // Prevent process.exit
52
+ try {
53
+ await command.parseAsync(["https://example.com", ...args], {
54
+ from: "user",
55
+ });
56
+ }
57
+ catch {
58
+ // Commander throws on exit, ignore
59
+ }
60
+ };
61
+ describe("command configuration", () => {
62
+ it("should create a command named detect", () => {
63
+ const command = detectCommand();
64
+ expect(command.name()).toBe("detect");
65
+ });
66
+ it("should have url as required argument", () => {
67
+ const command = detectCommand();
68
+ const args = command.registeredArguments;
69
+ expect(args[0]?.name()).toBe("url");
70
+ expect(args[0]?.required).toBe(true);
71
+ });
72
+ it("should have timeout option with default 10000", () => {
73
+ const command = detectCommand();
74
+ const options = command.options;
75
+ const timeoutOpt = options.find((o) => o.long === "--timeout");
76
+ expect(timeoutOpt).toBeDefined();
77
+ expect(timeoutOpt?.defaultValue).toBe(10000);
78
+ });
79
+ it("should have debug option", () => {
80
+ const command = detectCommand();
81
+ const options = command.options;
82
+ const debugOpt = options.find((o) => o.long === "--debug");
83
+ expect(debugOpt).toBeDefined();
84
+ });
85
+ it("should have evidence option", () => {
86
+ const command = detectCommand();
87
+ const options = command.options;
88
+ const evidenceOpt = options.find((o) => o.long === "--evidence");
89
+ expect(evidenceOpt).toBeDefined();
90
+ });
91
+ it("should have json option", () => {
92
+ const command = detectCommand();
93
+ const options = command.options;
94
+ const jsonOpt = options.find((o) => o.long === "--json");
95
+ expect(jsonOpt).toBeDefined();
96
+ });
97
+ });
98
+ describe("action execution", () => {
99
+ it("should call openPage with correct arguments", async () => {
100
+ await runCommand();
101
+ expect(openPage).toHaveBeenCalledWith("https://example.com", 10000, expect.any(Array));
102
+ });
103
+ it("should use custom timeout when provided", async () => {
104
+ await runCommand(["-t", "5000"]);
105
+ expect(openPage).toHaveBeenCalledWith("https://example.com", 5000, expect.any(Array));
106
+ });
107
+ it("should enable debug logging when --debug flag is set", async () => {
108
+ await runCommand(["--debug"]);
109
+ expect(setLogLevel).toHaveBeenCalled();
110
+ });
111
+ it("should log info messages on start", async () => {
112
+ await runCommand();
113
+ expect(logger.info).toHaveBeenCalledWith(expect.stringContaining("Starting detection"));
114
+ expect(logger.info).toHaveBeenCalledWith(expect.stringContaining("Timeout"));
115
+ });
116
+ it("should close browser and page after execution", async () => {
117
+ await runCommand();
118
+ expect(mockContext.page.close).toHaveBeenCalled();
119
+ expect(mockContext.browser.close).toHaveBeenCalled();
120
+ });
121
+ });
122
+ describe("detection output", () => {
123
+ it("should log message when no technologies detected", async () => {
124
+ vi.mocked(analyze).mockReturnValue([]);
125
+ await runCommand();
126
+ expect(logger.info).toHaveBeenCalledWith("No technologies detected.");
127
+ });
128
+ it("should print text output by default", async () => {
129
+ vi.mocked(analyze).mockReturnValue([{ name: "nginx" }]);
130
+ vi.mocked(makeDetectCommandOutput).mockReturnValue({
131
+ detectedSoftwares: [{ name: "nginx", confidence: "high" }],
132
+ });
133
+ await runCommand();
134
+ expect(printDetectCommandOutputAsText).toHaveBeenCalled();
135
+ expect(printDetectCommandOutputAsJSON).not.toHaveBeenCalled();
136
+ });
137
+ it("should print JSON output when --json flag is set", async () => {
138
+ vi.mocked(analyze).mockReturnValue([{ name: "nginx" }]);
139
+ vi.mocked(makeDetectCommandOutput).mockReturnValue({
140
+ detectedSoftwares: [{ name: "nginx", confidence: "high" }],
141
+ });
142
+ await runCommand(["--json"]);
143
+ expect(printDetectCommandOutputAsJSON).toHaveBeenCalled();
144
+ expect(printDetectCommandOutputAsText).not.toHaveBeenCalled();
145
+ });
146
+ it("should pass evidence flag to text output", async () => {
147
+ vi.mocked(analyze).mockReturnValue([{ name: "nginx" }]);
148
+ vi.mocked(makeDetectCommandOutput).mockReturnValue({
149
+ detectedSoftwares: [{ name: "nginx", confidence: "high" }],
150
+ });
151
+ await runCommand(["--evidence"]);
152
+ expect(printDetectCommandOutputAsText).toHaveBeenCalledWith(expect.any(Object), true);
153
+ });
154
+ });
155
+ describe("error handling", () => {
156
+ it("should handle playwright not installed error", async () => {
157
+ vi.mocked(openPage).mockRejectedValue(new Error("Executable doesn't exist at /path/to/chromium"));
158
+ await runCommand();
159
+ expect(logger.error).toHaveBeenCalledWith(expect.stringContaining("Playwright browsers are not installed"));
160
+ expect(process.exitCode).toBe(1);
161
+ });
162
+ it("should handle playwright install message error", async () => {
163
+ vi.mocked(openPage).mockRejectedValue(new Error("Please run: npx playwright install"));
164
+ await runCommand();
165
+ expect(logger.error).toHaveBeenCalledWith(expect.stringContaining("Playwright browsers are not installed"));
166
+ expect(process.exitCode).toBe(1);
167
+ });
168
+ it("should handle general errors", async () => {
169
+ vi.mocked(openPage).mockRejectedValue(new Error("Connection refused"));
170
+ await runCommand();
171
+ expect(logger.error).toHaveBeenCalledWith(expect.stringContaining("Detection failed"));
172
+ expect(process.exitCode).toBe(1);
173
+ });
174
+ it("should handle non-Error objects", async () => {
175
+ vi.mocked(openPage).mockRejectedValue("String error");
176
+ await runCommand();
177
+ expect(logger.error).toHaveBeenCalledWith(expect.stringContaining("Detection failed"));
178
+ expect(process.exitCode).toBe(1);
179
+ });
180
+ it("should not close browser/page if context is null on error", async () => {
181
+ vi.mocked(openPage).mockRejectedValue(new Error("Failed to launch"));
182
+ // Create new mockContext that won't be used
183
+ const unusedMockContext = {
184
+ browser: { close: vi.fn() },
185
+ page: { close: vi.fn() },
186
+ };
187
+ await runCommand();
188
+ // These should not be called because openPage threw before returning context
189
+ expect(unusedMockContext.page.close).not.toHaveBeenCalled();
190
+ expect(unusedMockContext.browser.close).not.toHaveBeenCalled();
191
+ });
192
+ });
193
+ });
194
+ //# sourceMappingURL=detect.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detect.test.js","sourceRoot":"","sources":["../../src/commands/detect.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=detect_utils.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detect_utils.test.d.ts","sourceRoot":"","sources":["../../src/commands/detect_utils.test.ts"],"names":[],"mappings":""}