@f5-sales-demo/xcsh 22.2.1 → 22.3.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.
package/src/qmd-smoke.ts CHANGED
@@ -6,7 +6,11 @@ import {
6
6
  createEmbeddedDocumentationRepository,
7
7
  type EmbeddedDocumentationRepository,
8
8
  } from "./internal-urls/documentation-repository";
9
- import type { DocumentationRepository, DocumentationSearchResult } from "./internal-urls/documentation-resolve";
9
+ import type {
10
+ DocumentationRepository,
11
+ DocumentationSearchResult,
12
+ DocumentationSource,
13
+ } from "./internal-urls/documentation-resolve";
10
14
  import { convertToPng } from "./utils/image-convert";
11
15
 
12
16
  export const QMD_SMOKE_SUCCESS = "XCSH_QMD_SMOKE_OK";
@@ -17,6 +21,10 @@ const EXPECTED_CATEGORY = "dns-dns-zone-clone-from-dns-domain";
17
21
  const WAF_QUERY = "configure web application firewall";
18
22
  const WAF_PATH = "docs/how-to/app-security/web-app-firewall";
19
23
  const WAF_TITLE = "Create Web Application Firewall";
24
+ const MARKETING_QUERY = "what is client side defense";
25
+ const MARKETING_PATH = "products/distributed-cloud-services/client-side-defense";
26
+ const MARKETING_TITLE = "F5 Distributed Cloud Client-Side Defense";
27
+ const MARKETING_SOURCE = "www-f5-com" as const;
20
28
  const DNS_QUERY = "set up DNS load balancer";
21
29
  const DNS_PATH = "dns-management/how-to/configure-dns-load-balancer";
22
30
  const DNS_TITLE = "Set Up DNS Load Balancer";
@@ -31,6 +39,8 @@ const EXPECTED_EVENTS = [
31
39
  "api-catalog-rank",
32
40
  "documentation-search",
33
41
  "documentation-read",
42
+ "documentation-marketing-search",
43
+ "documentation-marketing-read",
34
44
  "documentation-search",
35
45
  "documentation-read",
36
46
  "documentation-follow-up-read",
@@ -47,7 +57,7 @@ export interface QmdSmokeTraceEntry {
47
57
  readonly event: QmdSmokeEvent;
48
58
  readonly resource?: string;
49
59
  readonly title?: string;
50
- readonly source?: typeof SOURCE;
60
+ readonly source?: DocumentationSource;
51
61
  readonly category?: string;
52
62
  readonly outcome?: string;
53
63
  }
@@ -59,12 +69,12 @@ export interface QmdSmokeOptions {
59
69
  documentationRepository?: DocumentationRepository;
60
70
  }
61
71
 
62
- function searchUri(query: string): string {
63
- return `xcsh://documentation/?search=${encodeURIComponent(query)}&source=${SOURCE}&limit=1`;
72
+ function searchUri(query: string, source: DocumentationSource = SOURCE): string {
73
+ return `xcsh://documentation/?search=${encodeURIComponent(query)}&source=${source}&limit=1`;
64
74
  }
65
75
 
66
- function documentUri(stablePath: string): string {
67
- return `xcsh://documentation/${SOURCE}/${stablePath}/index.md`;
76
+ function documentUri(stablePath: string, source: DocumentationSource = SOURCE): string {
77
+ return `xcsh://documentation/${source}/${stablePath}/index.md`;
68
78
  }
69
79
 
70
80
  function assetUri(stablePath: string, filename: string): string {
@@ -75,11 +85,12 @@ function assertSearchResult(
75
85
  result: DocumentationSearchResult | undefined,
76
86
  expectedPath: string,
77
87
  expectedTitle: string,
78
- ): DocumentationSearchResult & { source: typeof SOURCE } {
79
- if (result?.source !== SOURCE || result.stablePath !== expectedPath || result.title !== expectedTitle) {
80
- throw new Error(`Documentation QMD smoke expected ${expectedTitle} at ${SOURCE}/${expectedPath}`);
88
+ expectedSource: DocumentationSource = SOURCE,
89
+ ): DocumentationSearchResult {
90
+ if (result?.source !== expectedSource || result.stablePath !== expectedPath || result.title !== expectedTitle) {
91
+ throw new Error(`Documentation QMD smoke expected ${expectedTitle} at ${expectedSource}/${expectedPath}`);
81
92
  }
82
- return result as DocumentationSearchResult & { source: typeof SOURCE };
93
+ return result;
83
94
  }
84
95
 
85
96
  /** Parse and strictly validate stdout from the installed-binary QMD smoke driver. */
@@ -109,6 +120,8 @@ export function parseQmdSmokeOutput(output: string): QmdSmokeTraceEntry[] {
109
120
  const expectedResources = [
110
121
  searchUri(WAF_QUERY),
111
122
  documentUri(WAF_PATH),
123
+ searchUri(MARKETING_QUERY, MARKETING_SOURCE),
124
+ documentUri(MARKETING_PATH, MARKETING_SOURCE),
112
125
  searchUri(DNS_QUERY),
113
126
  documentUri(DNS_PATH),
114
127
  documentUri(DNS_PATH),
@@ -126,16 +139,20 @@ export function parseQmdSmokeOutput(output: string): QmdSmokeTraceEntry[] {
126
139
  if (trace[index]?.title !== WAF_TITLE || trace[index]?.source !== SOURCE)
127
140
  throw new Error("QMD smoke trace contains unexpected WAF identity");
128
141
  }
129
- for (const index of [3, 4, 5]) {
142
+ for (const index of [3, 4]) {
143
+ if (trace[index]?.title !== MARKETING_TITLE || trace[index]?.source !== MARKETING_SOURCE)
144
+ throw new Error("QMD smoke trace contains unexpected marketing identity");
145
+ }
146
+ for (const index of [5, 6, 7]) {
130
147
  if (trace[index]?.title !== DNS_TITLE || trace[index]?.source !== SOURCE)
131
148
  throw new Error("QMD smoke trace contains unexpected DNS identity");
132
149
  }
133
- if (trace[6]?.outcome !== "no-match-no-fetch") throw new Error("QMD smoke trace did not fail closed");
134
- if (trace[7]?.outcome !== DOCUMENTATION_TOOLS_DISABLED_MESSAGE)
150
+ if (trace[8]?.outcome !== "no-match-no-fetch") throw new Error("QMD smoke trace did not fail closed");
151
+ if (trace[9]?.outcome !== DOCUMENTATION_TOOLS_DISABLED_MESSAGE)
135
152
  throw new Error("QMD smoke trace omitted the tools-disabled explanation");
136
- if (trace[8]?.source !== SOURCE || trace[8].outcome !== "image/png")
153
+ if (trace[10]?.source !== SOURCE || trace[10].outcome !== "image/png")
137
154
  throw new Error("QMD smoke trace contains an unexpected SVG conversion result");
138
- if (trace[9]?.outcome !== "ok") throw new Error("QMD smoke trace did not confirm SQLite startup");
155
+ if (trace[11]?.outcome !== "ok") throw new Error("QMD smoke trace did not confirm SQLite startup");
139
156
  return trace;
140
157
  }
141
158
 
@@ -173,6 +190,32 @@ export async function runQmdSmoke(options: QmdSmokeOptions = {}): Promise<string
173
190
  }
174
191
  emit({ event: "documentation-read", resource: documentUri(WAF_PATH), title: wafDocument.title, source: SOURCE });
175
192
 
193
+ const marketing = assertSearchResult(
194
+ (await documentation.search(MARKETING_QUERY, MARKETING_SOURCE, 1))[0],
195
+ MARKETING_PATH,
196
+ MARKETING_TITLE,
197
+ MARKETING_SOURCE,
198
+ );
199
+ emit({
200
+ event: "documentation-marketing-search",
201
+ resource: searchUri(MARKETING_QUERY, MARKETING_SOURCE),
202
+ title: marketing.title,
203
+ source: marketing.source,
204
+ });
205
+ const marketingDocument = await documentation.readDocument(MARKETING_SOURCE, MARKETING_PATH);
206
+ if (
207
+ marketingDocument?.title !== MARKETING_TITLE ||
208
+ !marketingDocument.markdown.includes("# F5 Client-Side Defense")
209
+ ) {
210
+ throw new Error("Documentation QMD smoke could not read exact marketing Markdown");
211
+ }
212
+ emit({
213
+ event: "documentation-marketing-read",
214
+ resource: documentUri(MARKETING_PATH, MARKETING_SOURCE),
215
+ title: marketingDocument.title,
216
+ source: MARKETING_SOURCE,
217
+ });
218
+
176
219
  const dns = assertSearchResult((await documentation.search(DNS_QUERY, SOURCE, 1))[0], DNS_PATH, DNS_TITLE);
177
220
  emit({ event: "documentation-search", resource: searchUri(DNS_QUERY), title: dns.title, source: dns.source });
178
221
  const dnsDocument = await documentation.readDocument(SOURCE, DNS_PATH);