@apica-io/asm-playwright-runner 1.0.0-dev.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.
@@ -0,0 +1,8 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <module type="WEB_MODULE" version="4">
3
+ <component name="NewModuleRootManager" inherit-compiler-output="true">
4
+ <exclude-output />
5
+ <content url="file://$MODULE_DIR$" />
6
+ <orderEntry type="sourceFolder" forTests="false" />
7
+ </component>
8
+ </module>
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.actionRegistry = void 0;
13
+ function assertStringContains(source, expected) {
14
+ return __awaiter(this, void 0, void 0, function* () {
15
+ const value = yield source();
16
+ if (!(value === null || value === void 0 ? void 0 : value.includes(expected))) {
17
+ throw new Error(`Expected "${expected}" in "${value}"`);
18
+ }
19
+ });
20
+ }
21
+ exports.actionRegistry = {
22
+ goto: (page, step) => __awaiter(void 0, void 0, void 0, function* () { return page.goto(step.url); }),
23
+ click: (page, step) => __awaiter(void 0, void 0, void 0, function* () { return page.click(step.selector); }),
24
+ type: (page, step) => __awaiter(void 0, void 0, void 0, function* () { return page.fill(step.selector, step.value); }),
25
+ screenshot: (page, step) => __awaiter(void 0, void 0, void 0, function* () { return page.screenshot({ path: step.path }); }),
26
+ reload: (page) => __awaiter(void 0, void 0, void 0, function* () { return page.reload(); }),
27
+ waitForSelector: (page, step) => __awaiter(void 0, void 0, void 0, function* () { return page.waitForSelector(step.selector); }),
28
+ hover: (page, step) => __awaiter(void 0, void 0, void 0, function* () { return page.hover(step.selector); }),
29
+ dblclick: (page, step) => __awaiter(void 0, void 0, void 0, function* () { return page.dblclick(step.selector); }),
30
+ check: (page, step) => __awaiter(void 0, void 0, void 0, function* () { return page.check(step.selector); }),
31
+ uncheck: (page, step) => __awaiter(void 0, void 0, void 0, function* () { return page.uncheck(step.selector); }),
32
+ selectOption: (page, step) => __awaiter(void 0, void 0, void 0, function* () { return page.selectOption(step.selector, step.value); }),
33
+ press: (page, step) => __awaiter(void 0, void 0, void 0, function* () { return page.press(step.selector, step.key); }),
34
+ waitForTimeout: (page, step) => __awaiter(void 0, void 0, void 0, function* () { return page.waitForTimeout(step.ms); }),
35
+ keyboardType: (page, step) => __awaiter(void 0, void 0, void 0, function* () { return page.keyboard.type(step.text); }),
36
+ keyboardPress: (page, step) => __awaiter(void 0, void 0, void 0, function* () { return page.keyboard.press(step.key); }),
37
+ assertText: (page, step) => __awaiter(void 0, void 0, void 0, function* () { return assertStringContains(() => page.textContent(step.selector), step.expected); }),
38
+ assertTitle: (page, step) => __awaiter(void 0, void 0, void 0, function* () { return assertStringContains(() => page.title(), step.expected); }),
39
+ uploadFile: (page, step) => __awaiter(void 0, void 0, void 0, function* () { return page.setInputFiles(step.selector, step.files); }),
40
+ waitForResponse: (page, step) => __awaiter(void 0, void 0, void 0, function* () { return page.waitForResponse(step.urlPattern); }),
41
+ assertVisible: (page, step) => __awaiter(void 0, void 0, void 0, function* () {
42
+ const isVisible = yield page.isVisible(step.selector);
43
+ if (!isVisible) {
44
+ throw new Error(`Expected element "${step.selector}" to be visible`);
45
+ }
46
+ })
47
+ };
@@ -0,0 +1,97 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
+ if (k2 === undefined) k2 = k;
5
+ var desc = Object.getOwnPropertyDescriptor(m, k);
6
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7
+ desc = { enumerable: true, get: function() { return m[k]; } };
8
+ }
9
+ Object.defineProperty(o, k2, desc);
10
+ }) : (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ o[k2] = m[k];
13
+ }));
14
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
15
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
16
+ }) : function(o, v) {
17
+ o["default"] = v;
18
+ });
19
+ var __importStar = (this && this.__importStar) || function (mod) {
20
+ if (mod && mod.__esModule) return mod;
21
+ var result = {};
22
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
23
+ __setModuleDefault(result, mod);
24
+ return result;
25
+ };
26
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
27
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
28
+ return new (P || (P = Promise))(function (resolve, reject) {
29
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
30
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
31
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
32
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
33
+ });
34
+ };
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ const commander_1 = require("commander");
40
+ const helper_1 = require("../lib/helper");
41
+ const log4js = __importStar(require("log4js"));
42
+ const fs_1 = __importDefault(require("fs"));
43
+ const runner_1 = require("../runner");
44
+ const cliLogConfig = {
45
+ appenders: {
46
+ out: {
47
+ type: "stdout",
48
+ },
49
+ },
50
+ categories: {
51
+ default: { appenders: ["out"], level: "INFO" },
52
+ },
53
+ };
54
+ var pack = (0, helper_1.getPackageInfo)();
55
+ let version = pack.version || "version unknown";
56
+ const program = new commander_1.Command();
57
+ let data;
58
+ program
59
+ .name("asm-playwright-runner")
60
+ .description("CLI wrapper for Playwright collections or scripts")
61
+ .version(version)
62
+ .argument("<collection>", "Flow JSON file or Playwright script")
63
+ .option("-b, --browser <browser>", "Browser type (chromium|firefox|webkit)", "chromium")
64
+ .option("-v, --verbose", "Print collection information on stdout", false)
65
+ .option("--chromiumPath <path>", "Custom Chromium/Chrome executable path")
66
+ .option("--headless", "Run browser headless (default true)", false)
67
+ .option("-r, --resultDir <dir>", "Result directory")
68
+ .option("-l, --logLevel <logLevel>", "Log level", "info")
69
+ .option("--extraHTTPHeaders <headers>", "Extra HTTP headers as JSON string")
70
+ .option("--timeout <timeout>", "Test timeout in ms")
71
+ .option("-rv, --returnResult", "Return the full structured test result object to the caller instead of only logging output", false)
72
+ .option("--sslClientCert <path>", "Client certificate (PEM)")
73
+ .option("--sslClientKey <path>", "Client certificate private key")
74
+ .option("--sslClientPassphrase <passphrase>", "Client certificate passphrase");
75
+ program.version(version);
76
+ program.parse(process.argv);
77
+ let log_level = program.opts().logLevel || "info";
78
+ log_level = log_level.toUpperCase();
79
+ cliLogConfig.categories.default.level =
80
+ ["DEBUG", "TRACE", "ERROR", "FATAL"].includes(log_level) ? log_level : "INFO";
81
+ cliLogConfig.categories.default.level = log_level;
82
+ log4js.configure(cliLogConfig);
83
+ var logger = log4js.getLogger(pack.name);
84
+ logger.info("%s (%s) started", pack.name, version);
85
+ // now construct runner
86
+ const runner = new runner_1.PlaywrightRunner();
87
+ (() => __awaiter(void 0, void 0, void 0, function* () {
88
+ const collection = program.args[0];
89
+ const options = program.opts();
90
+ if (!fs_1.default.existsSync(collection) || !fs_1.default.lstatSync(collection).isFile()) {
91
+ console.error("The specified collection file %s does not exist", collection);
92
+ process.exit(9);
93
+ }
94
+ yield runner.init(collection, options);
95
+ yield runner.run(collection, options);
96
+ yield runner.close();
97
+ }))();
@@ -0,0 +1,109 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __asyncValues = (this && this.__asyncValues) || function (o) {
12
+ if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
13
+ var m = o[Symbol.asyncIterator], i;
14
+ return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
15
+ function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
16
+ function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
17
+ };
18
+ var __importDefault = (this && this.__importDefault) || function (mod) {
19
+ return (mod && mod.__esModule) ? mod : { "default": mod };
20
+ };
21
+ Object.defineProperty(exports, "__esModule", { value: true });
22
+ exports.collectTraceFiles = exports.loadFlow = exports.traceZipToLines = exports.getPackageInfo = exports.readJsonFile = void 0;
23
+ const fs_1 = __importDefault(require("fs"));
24
+ const readline_1 = __importDefault(require("readline"));
25
+ const unzipper_1 = __importDefault(require("unzipper"));
26
+ const path_1 = __importDefault(require("path"));
27
+ function readJsonFile(pathName) {
28
+ try {
29
+ let content = fs_1.default.readFileSync(pathName);
30
+ return JSON.parse(content.toString());
31
+ }
32
+ catch (error) {
33
+ return {};
34
+ }
35
+ }
36
+ exports.readJsonFile = readJsonFile;
37
+ var packInfo;
38
+ function getPackageInfo() {
39
+ if (packInfo === undefined) {
40
+ packInfo = readJsonFile(`${__dirname}/../../package.json`);
41
+ }
42
+ return packInfo;
43
+ }
44
+ exports.getPackageInfo = getPackageInfo;
45
+ function traceZipToLines(tracePath) {
46
+ return __awaiter(this, void 0, void 0, function* () {
47
+ var _a, e_1, _b, _c;
48
+ const directory = yield unzipper_1.default.Open.file(tracePath);
49
+ const traceEntry = directory.files.find(file => file.path.endsWith("test.trace"));
50
+ const events = [];
51
+ if (!traceEntry) {
52
+ return events;
53
+ }
54
+ const stream = traceEntry.stream();
55
+ const rl = readline_1.default.createInterface({
56
+ input: stream,
57
+ crlfDelay: Infinity,
58
+ });
59
+ try {
60
+ for (var _d = true, rl_1 = __asyncValues(rl), rl_1_1; rl_1_1 = yield rl_1.next(), _a = rl_1_1.done, !_a; _d = true) {
61
+ _c = rl_1_1.value;
62
+ _d = false;
63
+ const line = _c;
64
+ const text = line.toString().trim();
65
+ if (!text) {
66
+ continue;
67
+ }
68
+ try {
69
+ events.push(JSON.parse(text));
70
+ }
71
+ catch (err) {
72
+ console.error("Invalid JSON:", text);
73
+ }
74
+ }
75
+ }
76
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
77
+ finally {
78
+ try {
79
+ if (!_d && !_a && (_b = rl_1.return)) yield _b.call(rl_1);
80
+ }
81
+ finally { if (e_1) throw e_1.error; }
82
+ }
83
+ return events;
84
+ });
85
+ }
86
+ exports.traceZipToLines = traceZipToLines;
87
+ function loadFlow(filePath) {
88
+ const raw = fs_1.default.readFileSync(filePath, "utf-8");
89
+ return JSON.parse(raw);
90
+ }
91
+ exports.loadFlow = loadFlow;
92
+ function collectTraceFiles(resultDir) {
93
+ const traces = [];
94
+ const walk = (dir) => {
95
+ for (const entry of fs_1.default.readdirSync(dir)) {
96
+ const fullPath = path_1.default.join(dir, entry);
97
+ const stat = fs_1.default.statSync(fullPath);
98
+ if (stat.isDirectory()) {
99
+ walk(fullPath);
100
+ }
101
+ else if (entry === "trace.zip") {
102
+ traces.push(fullPath);
103
+ }
104
+ }
105
+ };
106
+ walk(resultDir);
107
+ return traces;
108
+ }
109
+ exports.collectTraceFiles = collectTraceFiles;
@@ -0,0 +1,309 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.prepareTraceModel = exports.prepareStackData = exports.setResources = exports.setActions = exports.setHookActions = exports.zipResources = exports.getFileData = exports.getJsonFileData = void 0;
16
+ const unzipper_1 = __importDefault(require("unzipper"));
17
+ const archiver_1 = __importDefault(require("archiver"));
18
+ const path_1 = __importDefault(require("path"));
19
+ const fs_1 = __importDefault(require("fs"));
20
+ const runnerConfig_1 = require("../model/runnerConfig");
21
+ function getJsonFileData(tracePath, fileName) {
22
+ return __awaiter(this, void 0, void 0, function* () {
23
+ const directory = yield unzipper_1.default.Open.file(tracePath);
24
+ const file = directory.files.find(f => f.path.endsWith(fileName));
25
+ if (!file) {
26
+ return {};
27
+ }
28
+ const content = yield file.buffer();
29
+ return JSON.parse(content.toString("utf-8"));
30
+ });
31
+ }
32
+ exports.getJsonFileData = getJsonFileData;
33
+ function getFileData(tracePath, fileName) {
34
+ return __awaiter(this, void 0, void 0, function* () {
35
+ const directory = yield unzipper_1.default.Open.file(tracePath);
36
+ const traceFile = directory.files.find(f => f.path.endsWith(fileName));
37
+ if (!traceFile) {
38
+ return [];
39
+ }
40
+ const content = yield traceFile.buffer();
41
+ return content.toString('utf-8').split('\n').filter(Boolean);
42
+ });
43
+ }
44
+ exports.getFileData = getFileData;
45
+ function extractResources(zipPath_1) {
46
+ return __awaiter(this, arguments, void 0, function* (zipPath, targetImages = []) {
47
+ const baseDir = path_1.default.dirname(zipPath);
48
+ const runName = path_1.default.basename(baseDir);
49
+ const resultDir = path_1.default.dirname(baseDir);
50
+ const parentDir = resultDir === "." ? runName : resultDir;
51
+ const appendRunName = resultDir === "." ? [] : [runName];
52
+ const screenshotsDir = path_1.default.join(parentDir, runnerConfig_1.ResultDir.SCREENSHOT, ...appendRunName);
53
+ const sourceDir = path_1.default.join(parentDir, runnerConfig_1.ResultDir.SOURCE, ...appendRunName);
54
+ // Create folders if not exists
55
+ [screenshotsDir, sourceDir].forEach(dir => {
56
+ if (!fs_1.default.existsSync(dir)) {
57
+ fs_1.default.mkdirSync(dir, { recursive: true });
58
+ }
59
+ });
60
+ const directory = yield unzipper_1.default.Open.file(zipPath);
61
+ // Copy target images
62
+ const imagePromises = targetImages.map(targetImage => {
63
+ const fileEntry = directory.files.find((file) => file.path === `resources/${targetImage}`);
64
+ if (!fileEntry) {
65
+ return Promise.resolve();
66
+ }
67
+ const outputPath = path_1.default.join(screenshotsDir, targetImage);
68
+ return new Promise((resolve, reject) => {
69
+ fileEntry
70
+ .stream()
71
+ .pipe(fs_1.default.createWriteStream(outputPath))
72
+ .on('finish', () => {
73
+ resolve(true);
74
+ })
75
+ .on('error', reject);
76
+ });
77
+ });
78
+ // Copy all src@*.txt files
79
+ const sourcePromises = directory.files
80
+ .filter(file => file.path.startsWith('resources/') &&
81
+ /^src@.*\.txt$/.test(path_1.default.basename(file.path)))
82
+ .map(fileEntry => {
83
+ const fileName = path_1.default.basename(fileEntry.path);
84
+ const outputPath = path_1.default.join(sourceDir, fileName);
85
+ return new Promise((resolve, reject) => {
86
+ fileEntry
87
+ .stream()
88
+ .pipe(fs_1.default.createWriteStream(outputPath))
89
+ .on('finish', () => {
90
+ resolve(true);
91
+ })
92
+ .on('error', reject);
93
+ });
94
+ });
95
+ yield Promise.all([...imagePromises, ...sourcePromises]);
96
+ });
97
+ }
98
+ function zipResources(outputZipPath, screenshotsDir, sourceDir) {
99
+ return __awaiter(this, void 0, void 0, function* () {
100
+ return new Promise((resolve, reject) => {
101
+ const output = fs_1.default.createWriteStream(outputZipPath);
102
+ const archive = (0, archiver_1.default)("zip", { zlib: { level: 9 } });
103
+ output.on("close", resolve);
104
+ archive.on("error", reject);
105
+ archive.pipe(output);
106
+ if (fs_1.default.existsSync(screenshotsDir)) {
107
+ archive.directory(screenshotsDir, runnerConfig_1.ResultDir.SCREENSHOT);
108
+ }
109
+ if (fs_1.default.existsSync(sourceDir)) {
110
+ archive.directory(sourceDir, runnerConfig_1.ResultDir.SOURCE);
111
+ }
112
+ archive.finalize();
113
+ });
114
+ });
115
+ }
116
+ exports.zipResources = zipResources;
117
+ function setHookActions(traceRawResult) {
118
+ return __awaiter(this, void 0, void 0, function* () {
119
+ var _a;
120
+ const hookModel = { actions: [], stdio: [] };
121
+ const hookActions = {};
122
+ for (const [index, row] of traceRawResult.entries()) {
123
+ const entry = JSON.parse(row);
124
+ if (entry.type === "context-options") {
125
+ Object.assign(hookModel, {
126
+ origin: entry.origin,
127
+ browserName: entry.browserName,
128
+ playwrightVersion: entry.playwrightVersion,
129
+ options: entry.options,
130
+ platform: entry.platform,
131
+ wallTime: entry.wallTime,
132
+ startTime: entry.monotonicTime,
133
+ sdkLanguage: entry.sdkLanguage,
134
+ testIdAttributeName: entry.testIdAttributeName,
135
+ contextId: entry.contextId,
136
+ testTimeout: entry.testTimeout,
137
+ });
138
+ continue;
139
+ }
140
+ else if (entry.type === "stdout") {
141
+ (_a = hookModel === null || hookModel === void 0 ? void 0 : hookModel.stdio) === null || _a === void 0 ? void 0 : _a.push(entry);
142
+ }
143
+ else if (entry.type === "before") {
144
+ const action = {
145
+ type: "action",
146
+ callId: entry.callId,
147
+ stepId: entry.stepId,
148
+ parentId: entry.parentId,
149
+ startTime: entry.startTime,
150
+ class: entry.class,
151
+ method: entry.method,
152
+ title: entry.title,
153
+ params: entry.params,
154
+ stack: entry.stack,
155
+ log: [],
156
+ };
157
+ hookActions[entry.callId] = action;
158
+ hookModel.actions.push(action);
159
+ }
160
+ else if (entry.type === "after" && hookActions[entry.callId]) {
161
+ Object.assign(hookActions[entry.callId], {
162
+ endTime: entry.endTime,
163
+ annotations: entry.annotations,
164
+ });
165
+ }
166
+ if (index === (traceRawResult.length - 1) && entry.type === "after") {
167
+ hookModel.endTime = entry.endTime;
168
+ }
169
+ }
170
+ return hookModel;
171
+ });
172
+ }
173
+ exports.setHookActions = setHookActions;
174
+ function setActions(traceRawResult, traceModel, tracePath, stackData) {
175
+ return __awaiter(this, void 0, void 0, function* () {
176
+ var _a, _b, _c, _d, _e;
177
+ let beforeFlag = false;
178
+ let action = null;
179
+ let targetImages = [];
180
+ for (const row of traceRawResult) {
181
+ const entry = JSON.parse(row);
182
+ if (entry.type === 'context-options') {
183
+ traceModel.origin = entry.origin;
184
+ traceModel.browserName = entry.browserName;
185
+ traceModel.playwrightVersion = entry.playwrightVersion;
186
+ traceModel.options = entry.options;
187
+ traceModel.platform = entry.platform;
188
+ traceModel.wallTime = entry.wallTime;
189
+ traceModel.startTime = entry.monotonicTime;
190
+ traceModel.sdkLanguage = entry.sdkLanguage;
191
+ traceModel.testIdAttributeName = entry.testIdAttributeName;
192
+ traceModel.contextId = entry.contextId;
193
+ }
194
+ else if (entry.type == "event" || entry.type == "console") {
195
+ (_a = traceModel.events) === null || _a === void 0 ? void 0 : _a.push(entry);
196
+ }
197
+ else if (entry.type == "screencast-frame") {
198
+ let page = (_b = traceModel.pages) === null || _b === void 0 ? void 0 : _b.find(p => p.pageId === entry.pageId);
199
+ if (!page) {
200
+ page = {
201
+ pageId: entry.pageId,
202
+ screencastFrames: [],
203
+ };
204
+ (_c = traceModel.pages) === null || _c === void 0 ? void 0 : _c.push(page);
205
+ }
206
+ targetImages.push(entry.sha1);
207
+ page.screencastFrames.push(entry);
208
+ }
209
+ else {
210
+ if (entry.type == "before") {
211
+ action = {
212
+ callId: entry.callId,
213
+ class: entry.class,
214
+ method: entry.method,
215
+ startTime: entry.startTime,
216
+ type: "action",
217
+ params: entry.params,
218
+ pageId: entry.pageId,
219
+ log: [],
220
+ stack: stackData[entry.callId]
221
+ };
222
+ if (entry.class == "Frame") {
223
+ action.beforeSnapshot = entry.beforeSnapshot;
224
+ }
225
+ beforeFlag = true;
226
+ }
227
+ if (beforeFlag && action != null && action.callId == entry.callId) {
228
+ if (entry.type == "log") {
229
+ (_d = action.log) === null || _d === void 0 ? void 0 : _d.push({
230
+ time: entry.time,
231
+ message: entry.message
232
+ });
233
+ }
234
+ if (entry.type == "after") {
235
+ beforeFlag = false;
236
+ action.endTime = entry.endTime;
237
+ action.result = entry.result;
238
+ action.error = entry.error;
239
+ action.afterSnapshot = entry.afterSnapshot;
240
+ (_e = traceModel.actions) === null || _e === void 0 ? void 0 : _e.push(action);
241
+ }
242
+ }
243
+ }
244
+ }
245
+ traceModel.endTime = action === null || action === void 0 ? void 0 : action.endTime;
246
+ yield extractResources(tracePath, targetImages);
247
+ });
248
+ }
249
+ exports.setActions = setActions;
250
+ function setResources(resourceRawResult, traceModel) {
251
+ return __awaiter(this, void 0, void 0, function* () {
252
+ var _a;
253
+ for (const row of resourceRawResult) {
254
+ const entry = JSON.parse(row);
255
+ (_a = traceModel.resources) === null || _a === void 0 ? void 0 : _a.push(entry.snapshot);
256
+ }
257
+ });
258
+ }
259
+ exports.setResources = setResources;
260
+ function prepareStackData(stacksRawResult) {
261
+ return __awaiter(this, void 0, void 0, function* () {
262
+ const preparedData = {};
263
+ const files = stacksRawResult.files || [];
264
+ const stacks = stacksRawResult.stacks || [];
265
+ for (const stack of stacks) {
266
+ const [callId, frames] = stack;
267
+ preparedData[`call@${callId}`] = frames.map(([fileIndex, line, column, fn]) => ({
268
+ file: files[fileIndex] || `source-file-${fileIndex}`,
269
+ fileIndex: `source-file-${fileIndex}`,
270
+ line,
271
+ column,
272
+ functionName: fn || ""
273
+ }));
274
+ }
275
+ return preparedData;
276
+ });
277
+ }
278
+ exports.prepareStackData = prepareStackData;
279
+ function prepareTraceModel(tracePath, logLevel) {
280
+ return __awaiter(this, void 0, void 0, function* () {
281
+ const traceRawResult = yield getFileData(tracePath, "trace.trace");
282
+ const resourceRawResult = yield getFileData(tracePath, "trace.network");
283
+ const stacksRawResult = yield getJsonFileData(tracePath, "trace.stacks");
284
+ const traceModel = {
285
+ actions: [],
286
+ events: [],
287
+ resources: [],
288
+ errors: [],
289
+ pages: []
290
+ };
291
+ if (logLevel == runnerConfig_1.LogLevel.DEBUG) {
292
+ fs_1.default.writeFileSync(path_1.default.join(path_1.default.dirname(tracePath), "trace-raw-data.json"), JSON.stringify(traceRawResult, null, 2), "utf-8");
293
+ }
294
+ const stackData = yield prepareStackData(stacksRawResult);
295
+ yield setActions(traceRawResult, traceModel, tracePath, stackData);
296
+ yield setResources(resourceRawResult, traceModel);
297
+ const testHookResult = yield getFileData(tracePath, "test.trace");
298
+ if (testHookResult && testHookResult.length > 0) {
299
+ if (logLevel == runnerConfig_1.LogLevel.DEBUG) {
300
+ //raw data to validate data from trace
301
+ fs_1.default.writeFileSync(path_1.default.join(path_1.default.dirname(tracePath), "test-trace-raw-data.json"), JSON.stringify(testHookResult, null, 2), "utf-8");
302
+ }
303
+ const hookModel = yield setHookActions(testHookResult);
304
+ return [hookModel, traceModel];
305
+ }
306
+ return [traceModel];
307
+ });
308
+ }
309
+ exports.prepareTraceModel = prepareTraceModel;
package/dist/loader.js ADDED
@@ -0,0 +1,5 @@
1
+ import fs from "fs";
2
+ export function loadFlow(filePath) {
3
+ const raw = fs.readFileSync(filePath, "utf-8");
4
+ return JSON.parse(raw);
5
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ResultDir = exports.ScriptType = exports.LogLevel = exports.BrowserType = void 0;
4
+ var BrowserType;
5
+ (function (BrowserType) {
6
+ BrowserType["CHROMIUM"] = "chromium";
7
+ BrowserType["FIREFOX"] = "firefox";
8
+ BrowserType["WEBKIT"] = "webkit";
9
+ })(BrowserType || (exports.BrowserType = BrowserType = {}));
10
+ var LogLevel;
11
+ (function (LogLevel) {
12
+ LogLevel["INFO"] = "info";
13
+ LogLevel["DEBUG"] = "debug";
14
+ LogLevel["ERROR"] = "error";
15
+ })(LogLevel || (exports.LogLevel = LogLevel = {}));
16
+ var ScriptType;
17
+ (function (ScriptType) {
18
+ ScriptType["JSON"] = "json";
19
+ ScriptType["PLAYWRIGHT"] = "playwright";
20
+ ScriptType["PLAYWRIGHT_TEST"] = "playwright/test";
21
+ })(ScriptType || (exports.ScriptType = ScriptType = {}));
22
+ var ResultDir;
23
+ (function (ResultDir) {
24
+ ResultDir["BASE_DIR"] = "result";
25
+ ResultDir["SCREENSHOT"] = "screenshots";
26
+ ResultDir["SOURCE"] = "source";
27
+ })(ResultDir || (exports.ResultDir = ResultDir = {}));
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });