systemview 1.20.1 → 2.0.0

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.
@@ -1,8 +1,9 @@
1
1
  const fs = require("fs");
2
2
  const path = require("path");
3
- const { HttpClient } = require("systemlynx");
4
- const { createCookieClient } = require("./cookieClient");
5
- const Client = createCookieClient();
3
+ const { HttpClient, createClient } = require("systemlynx");
4
+ const { createCookieHttpClient } = require("./cookieClient");
5
+ const cookieHttpClient = createCookieHttpClient();
6
+ const Client = createClient(cookieHttpClient);
6
7
  const log = require("./logger");
7
8
 
8
9
  async function probeService(url) {
@@ -87,7 +87,4 @@ function createCookieHttpClient(extraHeaders = {}) {
87
87
  };
88
88
  }
89
89
 
90
- module.exports = {
91
- createCookieHttpClient,
92
- createCookieClient: (extraHeaders = {}) => createClient(createCookieHttpClient(extraHeaders)),
93
- };
90
+ module.exports = { createCookieHttpClient };
package/cli/index.js CHANGED
@@ -14,8 +14,11 @@ const appIsRunning = require("./appIsRunning");
14
14
  const openBrowser = require("./openBrowser");
15
15
  const connectService = require("./connectService");
16
16
  const probe = require("./probe");
17
- const { HttpClient } = require("systemlynx");
18
- const { createCookieClient } = require("./cookieClient");
17
+ const logsCommand = require("./logs");
18
+ const { HttpClient, createClient } = require("systemlynx");
19
+ const { createCookieHttpClient } = require("./cookieClient");
20
+ const cookieHttpClient = createCookieHttpClient();
21
+ const Client = createClient(cookieHttpClient);
19
22
 
20
23
  const DEFAULT_PORT = 3000;
21
24
  const VERSION = require("../package.json").version;
@@ -84,7 +87,7 @@ async function open() {
84
87
  } catch {}
85
88
  } else {
86
89
  try {
87
- const { SystemView } = await createCookieClient().loadService(api);
90
+ const { SystemView } = await Client.loadService(api);
88
91
  connectedServices = (await SystemView.getServices(project_code)) || [];
89
92
  } catch {}
90
93
  }
@@ -149,6 +152,23 @@ async function quitApp() {
149
152
  headers: flags.headers,
150
153
  });
151
154
  process.exit(exitCode || 0);
155
+ } else if (command === "logs") {
156
+ const url = `http://localhost:${DEFAULT_PORT}`;
157
+ const api = `${url}/systemview/api`;
158
+ if (!(await appIsRunning(api))) {
159
+ await launchApp(DEFAULT_PORT);
160
+ }
161
+ await logsCommand(url, input[1], input[2], {
162
+ level: flags.level,
163
+ limit: flags.limit,
164
+ clear: flags.clear,
165
+ json: flags.json,
166
+ follow: command === "follow" || flags.follow,
167
+ verbose: flags.verbose,
168
+ filter: flags.filter,
169
+ or: flags.or,
170
+ });
171
+ process.exit(0);
152
172
  } else {
153
173
  await startApp();
154
174
  }
package/cli/launchApp.js CHANGED
@@ -17,6 +17,7 @@ module.exports = async function launchApp(port, { interactive = false } = {}) {
17
17
  if (interactive) {
18
18
  log.info("SystemView is running from another terminal");
19
19
  logConnection();
20
+ return startLineReader(ui);
20
21
  }
21
22
  return;
22
23
  }
package/cli/listTests.js CHANGED
@@ -1,12 +1,15 @@
1
1
  const fs = require("fs");
2
2
  const path = require("path");
3
- const { createCookieClient } = require("./cookieClient");
3
+ const { createClient } = require("systemlynx");
4
+ const { createCookieHttpClient } = require("./cookieClient");
4
5
  const log = require("./logger");
5
6
  const chalk = require("chalk");
6
7
 
8
+ const cookieHttpClient = createCookieHttpClient();
9
+ const Client = createClient(cookieHttpClient);
10
+
7
11
  module.exports = async function listTests(url, project_code, namespace, { manifest: manifestPath, verbose = false } = {}) {
8
12
  const api = `${url}/systemview/api`;
9
- const Client = createCookieClient();
10
13
 
11
14
  if (!project_code) {
12
15
  await listAllProjects(api, Client, verbose);
@@ -30,7 +33,7 @@ module.exports = async function listTests(url, project_code, namespace, { manife
30
33
 
31
34
  let testList = [];
32
35
  try {
33
- const svc = createCookieClient().createService(system.connectionData);
36
+ const svc = Client.createService(system.connectionData);
34
37
  testList = await svc.Plugin.getTests();
35
38
  } catch {
36
39
  console.log(`${servicePrefix}${chalk.dim(serviceId)} ${chalk.dim("(could not load tests)")}`);
package/cli/logs.js ADDED
@@ -0,0 +1,219 @@
1
+ const fs = require("fs");
2
+ const path = require("path");
3
+ const chalk = require("chalk");
4
+ const log = require("./logger");
5
+ const { createClient } = require("systemlynx");
6
+ const { createCookieHttpClient } = require("./cookieClient");
7
+ const cookieHttpClient = createCookieHttpClient();
8
+ const Client = createClient(cookieHttpClient);
9
+
10
+ const LEVEL_COLOR = {
11
+ trace: (s) => chalk.dim(s),
12
+ info: (s) => chalk.white(s),
13
+ warn: (s) => chalk.yellow(s),
14
+ error: (s) => chalk.red(s),
15
+ debug: (s) => chalk.blue(s),
16
+ };
17
+
18
+ function colorLevel(level) {
19
+ const fn = LEVEL_COLOR[level] || ((s) => s);
20
+ return fn((level || "info").padEnd(5));
21
+ }
22
+
23
+ const SKIP_KEYS = new Set([
24
+ "timestamp",
25
+ "projectCode",
26
+ "serviceId",
27
+ "moduleMethod",
28
+ "traceId",
29
+ "level",
30
+ "message",
31
+ "duration",
32
+ ]);
33
+
34
+ function formatRow(entry, verbose) {
35
+ const d = new Date(entry.timestamp);
36
+ const time =
37
+ d.toLocaleDateString("en-US", { month: "short", day: "numeric", year: "numeric" }) +
38
+ " " +
39
+ d.toLocaleTimeString("en-US", { hour12: false });
40
+ const project = entry.projectCode || "—";
41
+ const service = entry.serviceId || "—";
42
+ const method = entry.moduleMethod || "—";
43
+ const level = colorLevel(entry.level);
44
+ const msg = entry.message || "";
45
+ const dur = entry.duration != null ? chalk.dim(` ${entry.duration}ms`) : "";
46
+ const traceId = chalk.dim(entry.traceId || "—");
47
+ const main = ` ${chalk.dim(time)} ${chalk.cyan(project)} › ${chalk.cyan(service)} ${method.padEnd(15)} ${level} ${traceId} ${msg}${dur}`;
48
+ if (verbose) {
49
+ const extra = {};
50
+ Object.keys(entry).forEach((k) => {
51
+ if (!SKIP_KEYS.has(k)) extra[k] = entry[k];
52
+ });
53
+ if (Object.keys(extra).length) {
54
+ return (
55
+ main +
56
+ "\n" +
57
+ JSON.stringify(extra, null, 2)
58
+ .split("\n")
59
+ .map((l) => " " + chalk.yellow(l))
60
+ .join("\n")
61
+ );
62
+ }
63
+ }
64
+ return main;
65
+ }
66
+
67
+ function parseFilters(filters) {
68
+ return (filters || [])
69
+ .map((f) => {
70
+ const eq = f.indexOf("=");
71
+ if (eq === -1) return null;
72
+ return { field: f.slice(0, eq), value: f.slice(eq + 1) };
73
+ })
74
+ .filter(Boolean);
75
+ }
76
+
77
+ function matchesFilters(entry, andFilters, orFilters) {
78
+ const check = ({ field, value }) => {
79
+ const v = entry[field];
80
+ return v != null && String(v).includes(value);
81
+ };
82
+ const andPass = andFilters.length === 0 || andFilters.every(check);
83
+ const orPass = orFilters.length === 0 || orFilters.some(check);
84
+ if (andFilters.length && orFilters.length) return andPass || orPass;
85
+ return andPass && orPass;
86
+ }
87
+
88
+ module.exports = async function logsCommand(
89
+ url,
90
+ projectCode,
91
+ namespace,
92
+ { level, limit = 50, clear, json, follow, current, verbose, filter, or: orFilters },
93
+ ) {
94
+ const andFilters = parseFilters(filter);
95
+ const orFiltersParsed = parseFilters(orFilters);
96
+
97
+ if (follow) {
98
+ const manifestFile = path.join(process.cwd(), "systemview.manifest.json");
99
+ if (!fs.existsSync(manifestFile)) {
100
+ log.warn("No manifest found. Use: systemview connect <serviceId> <url>");
101
+ return;
102
+ }
103
+ const manifest = JSON.parse(fs.readFileSync(manifestFile, "utf8"));
104
+ const services = manifest.services || [manifest];
105
+ if (!services.length) {
106
+ log.warn("No services in manifest. Use: systemview connect <serviceId> <url>");
107
+ return;
108
+ }
109
+
110
+ console.log("");
111
+ console.log(chalk.bold(" Streaming logs"));
112
+ console.log("");
113
+
114
+ console.log(chalk.dim(` Services (${services.length}):`));
115
+ const connected = [];
116
+ for (const { serviceId, system } of services) {
117
+ const { serviceUrl } = system.connectionData;
118
+ try {
119
+ const svc = await Client.loadService(serviceUrl);
120
+ svc.SystemViewLogs.on("log", (entry) => {
121
+ if (namespace && !(entry.moduleMethod && entry.moduleMethod.includes(namespace))) return;
122
+ if (andFilters.length || orFiltersParsed.length) {
123
+ if (!matchesFilters(entry, andFilters, orFiltersParsed)) return;
124
+ }
125
+ if (level && entry.level !== level) return;
126
+ console.log(formatRow(entry, verbose));
127
+ });
128
+ console.log(` ${chalk.green("✓")} ${chalk.cyan(serviceId).padEnd(20)} ${chalk.dim(serviceUrl)}`);
129
+ connected.push(serviceId);
130
+ } catch (err) {
131
+ console.log(` ${chalk.red("✗")} ${chalk.cyan(serviceId).padEnd(20)} ${chalk.dim(serviceUrl)} ${chalk.red("(failed to connect)")}`);
132
+ }
133
+ }
134
+
135
+ const activeFilters = [];
136
+ if (namespace) activeFilters.push(`namespace: ${chalk.white(namespace)}`);
137
+ if (level) activeFilters.push(`level: ${chalk.white(level)}`);
138
+ if (andFilters.length) activeFilters.push(`filter: ${chalk.white(andFilters.map((f) => `${f.field}=${f.value}`).join(", "))}`);
139
+ if (orFiltersParsed.length) activeFilters.push(`or: ${chalk.white(orFiltersParsed.map((f) => `${f.field}=${f.value}`).join(", "))}`);
140
+ if (verbose) activeFilters.push(`verbose: ${chalk.white("on")}`);
141
+
142
+ if (activeFilters.length) {
143
+ console.log("");
144
+ console.log(chalk.dim(` Filters:`));
145
+ activeFilters.forEach((f) => console.log(` ${chalk.dim(f)}`));
146
+ }
147
+
148
+ console.log("");
149
+
150
+ if (!connected.length) {
151
+ log.warn("No services connected.");
152
+ return;
153
+ }
154
+
155
+ if (current) {
156
+ try {
157
+ const api = `${url}/systemview/api`;
158
+ const { SystemView } = await Client.loadService(api);
159
+ const all = await SystemView.getLogs({ projectCode: manifest.projectCode, level, limit });
160
+ let entries = all || [];
161
+ if (namespace) entries = entries.filter((e) => e.moduleMethod && e.moduleMethod.includes(namespace));
162
+ if (andFilters.length || orFiltersParsed.length) entries = entries.filter((e) => matchesFilters(e, andFilters, orFiltersParsed));
163
+ if (entries.length) {
164
+ console.log(chalk.dim(` ── current (${entries.length}) ──`));
165
+ entries.forEach((e) => console.log(formatRow(e, verbose)));
166
+ console.log(chalk.dim(` ── streaming ──`));
167
+ }
168
+ } catch (err) {
169
+ log.warn("Could not fetch current logs: " + err.message);
170
+ }
171
+ }
172
+
173
+ return;
174
+ }
175
+
176
+ const api = `${url}/systemview/api`;
177
+ const { SystemView } = await Client.loadService(api);
178
+
179
+ if (clear) {
180
+ const confirmed = await promptConfirm("Clear all logs? (y/N) ");
181
+ if (!confirmed) { log.warn("Aborted."); return; }
182
+ await SystemView.clearLogs();
183
+ log.success("Logs cleared.");
184
+ return;
185
+ }
186
+
187
+ const entries = await (async () => {
188
+ const all = await SystemView.getLogs({ projectCode, level, limit });
189
+ let filtered = all || [];
190
+ if (namespace) filtered = filtered.filter((e) => e.moduleMethod && e.moduleMethod.includes(namespace));
191
+ if (andFilters.length || orFiltersParsed.length) filtered = filtered.filter((e) => matchesFilters(e, andFilters, orFiltersParsed));
192
+ return filtered;
193
+ })();
194
+
195
+ if (json) {
196
+ console.log(JSON.stringify(entries, null, 2));
197
+ return;
198
+ }
199
+
200
+ if (!entries.length) {
201
+ log.warn("No logs found.");
202
+ return;
203
+ }
204
+
205
+ console.log("");
206
+ entries.forEach((e) => console.log(formatRow(e, verbose)));
207
+ console.log("");
208
+ log.plain(chalk.dim(` ${entries.length} entries`));
209
+ };
210
+
211
+ function promptConfirm(question) {
212
+ return new Promise((resolve) => {
213
+ process.stdout.write(question);
214
+ process.stdin.setEncoding("utf8");
215
+ process.stdin.once("data", (data) => {
216
+ resolve(data.trim().toLowerCase() === "y");
217
+ });
218
+ });
219
+ }
package/cli/probe.js CHANGED
@@ -1,8 +1,12 @@
1
1
  const fs = require("fs");
2
2
  const path = require("path");
3
- const { createCookieClient } = require("./cookieClient");
3
+ const { createClient } = require("systemlynx");
4
+ const { createCookieHttpClient } = require("./cookieClient");
4
5
  const log = require("./logger");
5
6
 
7
+ const cookieHttpClient = createCookieHttpClient();
8
+ const Client = createClient(cookieHttpClient);
9
+
6
10
  module.exports = async function probe(namespace, argsStr, { json = false, manifest: manifestPath, headers: cliHeaders = {} } = {}) {
7
11
  if (!namespace) {
8
12
  log.error("Usage: systemview probe <ServiceId.Module.method> [args]");
@@ -52,7 +56,8 @@ module.exports = async function probe(namespace, argsStr, { json = false, manife
52
56
  if (!json) log.info(`${serviceId}.${moduleName}.${methodName}(${argsStr || ""})`);
53
57
 
54
58
  try {
55
- const client = createCookieClient(extraHeaders).createService(service.system.connectionData);
59
+ const client = Client.createService(service.system.connectionData);
60
+ if (Object.keys(extraHeaders).length) client.setHeaders(extraHeaders);
56
61
  const result = await client[moduleName][methodName](...args);
57
62
  if (json) {
58
63
  process.stdout.write(JSON.stringify({ serviceId, moduleName, methodName, args, result }, null, 2) + "\n");
package/cli/runTests.js CHANGED
@@ -1,6 +1,9 @@
1
1
  const fs = require("fs");
2
2
  const path = require("path");
3
- const { createCookieClient } = require("./cookieClient");
3
+ const { createClient } = require("systemlynx");
4
+ const { createCookieHttpClient } = require("./cookieClient");
5
+ const cookieHttpClient = createCookieHttpClient();
6
+ const Client = createClient(cookieHttpClient);
4
7
  const { initializeSavedTests } = require("../testing-utilities/transformTests");
5
8
  const FullTestController = require("../testing-utilities/FullTestController");
6
9
  const log = require("./logger");
@@ -72,7 +75,6 @@ module.exports = async function runTests(
72
75
  }
73
76
 
74
77
  const extraHeaders = { ...manifestHeaders, ...cliHeaders };
75
- const Client = createCookieClient(extraHeaders);
76
78
 
77
79
  if (!json) {
78
80
  connectedServices.forEach(({ serviceId, system }) => {
@@ -121,7 +123,7 @@ module.exports = async function runTests(
121
123
  if (!json) log.info(`Initializing tests for ${serviceId}...`);
122
124
 
123
125
  try {
124
- const initialized = initializeSavedTests(testList, connectedServices, Client);
126
+ const initialized = initializeSavedTests(testList, connectedServices, Client, extraHeaders);
125
127
  const { passed, failed, jsonTests, failures } = await runAllTests(
126
128
  initialized,
127
129
  url,
@@ -376,8 +378,7 @@ async function resolveServices(api, project_code, manifestPath) {
376
378
  }
377
379
  }
378
380
 
379
- const BaseClient = createCookieClient();
380
- const services = await getConnectedServices(api, project_code, BaseClient);
381
+ const services = await getConnectedServices(api, project_code, Client);
381
382
  return { services, probeHeaders: {} };
382
383
  }
383
384
 
@@ -1,6 +1,7 @@
1
1
  const runTests = require("./runTests");
2
2
  const cli = require("./utils/cli");
3
3
  const openBrowser = require("./openBrowser");
4
+ const logsCommand = require("./logs");
4
5
  const readline = require("readline");
5
6
 
6
7
  module.exports = function startLineReader(url) {
@@ -8,23 +9,42 @@ module.exports = function startLineReader(url) {
8
9
  input: process.stdin,
9
10
  output: process.stdout,
10
11
  });
12
+
11
13
  const handleInput = (input = "") => {
12
- const args = input.split(" ").map((s) => s.trim());
13
- const command = args.shift();
14
+ const parts = input.trim().split(/\s+/);
15
+ const command = parts[0];
16
+ const args = parts.slice(1);
17
+
18
+ const flags = { filter: [], or: [] };
19
+ const positional = [];
20
+ for (let i = 0; i < args.length; i++) {
21
+ if (args[i] === "--level" && args[i + 1]) { flags.level = args[++i]; }
22
+ else if (args[i] === "--limit" && args[i + 1]) { flags.limit = parseInt(args[++i], 10); }
23
+ else if (args[i] === "--filter" && args[i + 1]) { flags.filter.push(args[++i]); }
24
+ else if (args[i] === "--or" && args[i + 1]) { flags.or.push(args[++i]); }
25
+ else if (args[i] === "--verbose") { flags.verbose = true; }
26
+ else if (args[i] === "--current") { flags.current = true; }
27
+ else if (args[i] === "--json") { flags.json = true; }
28
+ else if (!args[i].startsWith("--")) { positional.push(args[i]); }
29
+ }
30
+
14
31
  if (["exit", "q", "shutdown", "stop"].includes(command)) {
15
32
  process.exit(0);
16
33
  } else if (command === "test") {
17
- try {
18
- runTests(url, ...args);
19
- } catch (error) {
20
- console.error("Error executing tests:", error.message);
21
- }
34
+ try { runTests(url, positional[0], positional[1]); } catch (e) { console.error(e.message); }
35
+ lineReader.prompt();
36
+ } else if (command === "logs") {
37
+ logsCommand(url, positional[0], positional[1], { ...flags, follow: true, current: flags.current });
38
+ } else if (command === "clearlogs" || command === "flush") {
39
+ logsCommand(url, null, null, { clear: true, follow: false });
22
40
  } else if (command === "help") {
23
41
  cli.showHelp(0);
24
42
  } else if (command === "open") {
25
- openBrowser(url, ...args);
43
+ openBrowser(url, positional[0], positional[1]);
44
+ lineReader.prompt();
45
+ } else {
46
+ lineReader.prompt();
26
47
  }
27
- lineReader.prompt();
28
48
  };
29
49
 
30
50
  lineReader.prompt();
package/cli/utils/cli.js CHANGED
@@ -8,6 +8,7 @@ const HELP_TEXT = `
8
8
  start [port] Launch SystemView UI (default port 3000)
9
9
  test <projectCode> [namespace] Run saved tests for a project
10
10
  list [projectCode] [namespace] List projects, services, or tests
11
+ logs [projectCode] [namespace] View log entries
11
12
  connect <serviceId> <url> Register a service and write manifest
12
13
  connect Re-probe all services in existing manifest
13
14
  probe <ServiceId.Module.method> [args] Call a method ad-hoc
@@ -25,6 +26,10 @@ const HELP_TEXT = `
25
26
  --dry-run Print which tests would run without executing
26
27
  --phase <before|main|events|after> Run only specified phase(s), comma-separated
27
28
  --index <n> Run only action at index n within each phase (0-based)
29
+ --level <trace|info|warn|error|debug> logs: filter by level
30
+ --limit <n> logs: max entries to return (default 50)
31
+ --follow logs: stream new entries as they arrive
32
+ --clear logs: wipe the log file
28
33
 
29
34
  Examples:
30
35
  systemview start
@@ -44,7 +49,7 @@ const HELP_TEXT = `
44
49
 
45
50
  const rawArgs = process.argv.slice(2);
46
51
 
47
- const flagValueArgs = ["--manifest", "--header", "--skip", "--phase", "--index"];
52
+ const flagValueArgs = ["--manifest", "--header", "--skip", "--phase", "--index", "--level", "--limit", "--follow", "--filter", "--or"];
48
53
 
49
54
  const flags = {
50
55
  json: rawArgs.includes("--json"),
@@ -73,6 +78,28 @@ const flags = {
73
78
  });
74
79
  return result;
75
80
  })(),
81
+ level: (() => {
82
+ const i = rawArgs.indexOf("--level");
83
+ return i !== -1 ? rawArgs[i + 1] : null;
84
+ })(),
85
+ limit: (() => {
86
+ const i = rawArgs.indexOf("--limit");
87
+ if (i === -1) return undefined;
88
+ const val = parseInt(rawArgs[i + 1], 10);
89
+ return isNaN(val) ? undefined : val;
90
+ })(),
91
+ follow: rawArgs.includes("--follow") || rawArgs.includes("-f"),
92
+ filter: (() => {
93
+ const result = [];
94
+ rawArgs.forEach((a, i) => { if (a === "--filter" && rawArgs[i + 1]) result.push(rawArgs[i + 1]); });
95
+ return result;
96
+ })(),
97
+ or: (() => {
98
+ const result = [];
99
+ rawArgs.forEach((a, i) => { if (a === "--or" && rawArgs[i + 1]) result.push(rawArgs[i + 1]); });
100
+ return result;
101
+ })(),
102
+ clear: rawArgs.includes("--clear"),
76
103
  headers: (() => {
77
104
  const result = {};
78
105
  rawArgs.forEach((a, i) => {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "systemview",
3
3
  "description": "A documentation and testing suite for SystemLynx",
4
- "version": "1.20.1",
4
+ "version": "2.0.0",
5
5
  "license": "UNLICENSED",
6
6
  "bin": {
7
7
  "systemview": "cli/index.js"
@@ -16,8 +16,8 @@
16
16
  "chalk": "^4.1.2",
17
17
  "express": "^4.18.2",
18
18
  "moment": "^2.29.1",
19
- "systemlynx": "^1.19.12",
20
- "systemlynx-client": "^1.19.14",
19
+ "systemlynx": "^2.0.0",
20
+ "systemlynx-client": "^2.0.0",
21
21
  "web-vitals": "^0.2.4"
22
22
  },
23
23
  "scripts": {
@@ -13,6 +13,7 @@ module.exports = function Test({
13
13
  editMode = true,
14
14
  logger,
15
15
  client,
16
+ extraHeaders,
16
17
  }) {
17
18
  this.index = index;
18
19
  this.connection = {};
@@ -101,7 +102,7 @@ module.exports = function Test({
101
102
  const { connectionData } = service.system;
102
103
 
103
104
  this.connection[serviceId] = (client || Client).createService(connectionData);
104
- this.connection[serviceId].setHeaders({ Origin: `http://localhost:${3000}` });
105
+ this.connection[serviceId].setHeaders({ Origin: `http://localhost:${3000}`, ...(extraHeaders || {}) });
105
106
  }
106
107
 
107
108
  return this;
@@ -1,23 +1,23 @@
1
1
  const { Argument } = require("./Argument.class");
2
2
  const Test = require("./Test.class");
3
3
 
4
- function initializeSavedTests(savedTests, connectedServices, client) {
4
+ function initializeSavedTests(savedTests, connectedServices, client, extraHeaders) {
5
5
  return savedTests.map((ft) => {
6
6
  // context matters
7
7
  const newTests = [];
8
8
  const { title, namespace } = ft;
9
9
 
10
10
  const Before = ft.Before.map((test) =>
11
- resetTestClass(test, newTests, connectedServices, false, client)
11
+ resetTestClass(test, newTests, connectedServices, false, client, extraHeaders)
12
12
  );
13
13
  const Main = ft.Main.map((test) =>
14
- resetTestClass(test, newTests, connectedServices, false, client)
14
+ resetTestClass(test, newTests, connectedServices, false, client, extraHeaders)
15
15
  );
16
16
  const Events = ft.Events.map((test) =>
17
- resetTestClass(test, newTests, connectedServices, false, client)
17
+ resetTestClass(test, newTests, connectedServices, false, client, extraHeaders)
18
18
  );
19
19
  const After = ft.After.map((test) =>
20
- resetTestClass(test, newTests, connectedServices, false, client)
20
+ resetTestClass(test, newTests, connectedServices, false, client, extraHeaders)
21
21
  );
22
22
  newTests.push(Before);
23
23
  newTests.push(Main);
@@ -27,7 +27,7 @@ function initializeSavedTests(savedTests, connectedServices, client) {
27
27
  });
28
28
  }
29
29
 
30
- const resetTestClass = (test, FullTest, connectedServices, editMode, client) => {
30
+ const resetTestClass = (test, FullTest, connectedServices, editMode, client, extraHeaders) => {
31
31
  return new Test({
32
32
  ...test,
33
33
  args: test.args.map(
@@ -36,6 +36,7 @@ const resetTestClass = (test, FullTest, connectedServices, editMode, client) =>
36
36
  ),
37
37
  editMode,
38
38
  client,
39
+ extraHeaders,
39
40
  }).getConnection(connectedServices);
40
41
  };
41
42