@apica-io/asm-playwright-runner 1.0.0-dev.1 → 1.0.0-dev.3
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/dist/lib/parser.js
CHANGED
|
@@ -92,6 +92,10 @@ function extractResources(zipPath_1) {
|
|
|
92
92
|
.on('error', reject);
|
|
93
93
|
});
|
|
94
94
|
});
|
|
95
|
+
const errorContext = path_1.default.join(baseDir, "error-context.md");
|
|
96
|
+
if (fs_1.default.existsSync(errorContext)) {
|
|
97
|
+
fs_1.default.copyFileSync(errorContext, path_1.default.join(sourceDir, "error-context.md"));
|
|
98
|
+
}
|
|
95
99
|
yield Promise.all([...imagePromises, ...sourcePromises]);
|
|
96
100
|
});
|
|
97
101
|
}
|
|
@@ -116,8 +120,8 @@ function zipResources(outputZipPath, screenshotsDir, sourceDir) {
|
|
|
116
120
|
exports.zipResources = zipResources;
|
|
117
121
|
function setHookActions(traceRawResult) {
|
|
118
122
|
return __awaiter(this, void 0, void 0, function* () {
|
|
119
|
-
var _a;
|
|
120
|
-
const hookModel = { actions: [], stdio: [] };
|
|
123
|
+
var _a, _b;
|
|
124
|
+
const hookModel = { actions: [], stdio: [], errors: [] };
|
|
121
125
|
const hookActions = {};
|
|
122
126
|
for (const [index, row] of traceRawResult.entries()) {
|
|
123
127
|
const entry = JSON.parse(row);
|
|
@@ -137,7 +141,7 @@ function setHookActions(traceRawResult) {
|
|
|
137
141
|
});
|
|
138
142
|
continue;
|
|
139
143
|
}
|
|
140
|
-
else if (entry.type === "stdout") {
|
|
144
|
+
else if (entry.type === "stdout" || entry.type === "stderr") {
|
|
141
145
|
(_a = hookModel === null || hookModel === void 0 ? void 0 : hookModel.stdio) === null || _a === void 0 ? void 0 : _a.push(entry);
|
|
142
146
|
}
|
|
143
147
|
else if (entry.type === "before") {
|
|
@@ -161,10 +165,17 @@ function setHookActions(traceRawResult) {
|
|
|
161
165
|
Object.assign(hookActions[entry.callId], {
|
|
162
166
|
endTime: entry.endTime,
|
|
163
167
|
annotations: entry.annotations,
|
|
168
|
+
error: entry.error,
|
|
164
169
|
});
|
|
165
170
|
}
|
|
171
|
+
else if (entry.type == "error") {
|
|
172
|
+
(_b = hookModel.errors) === null || _b === void 0 ? void 0 : _b.push(entry);
|
|
173
|
+
}
|
|
166
174
|
if (index === (traceRawResult.length - 1) && entry.type === "after") {
|
|
167
175
|
hookModel.endTime = entry.endTime;
|
|
176
|
+
if (hookModel.endTime != null && hookModel.startTime) {
|
|
177
|
+
hookModel.duration = Number((hookModel.endTime - hookModel.startTime).toFixed(3));
|
|
178
|
+
}
|
|
168
179
|
}
|
|
169
180
|
}
|
|
170
181
|
return hookModel;
|
|
@@ -173,7 +184,7 @@ function setHookActions(traceRawResult) {
|
|
|
173
184
|
exports.setHookActions = setHookActions;
|
|
174
185
|
function setActions(traceRawResult, traceModel, tracePath, stackData) {
|
|
175
186
|
return __awaiter(this, void 0, void 0, function* () {
|
|
176
|
-
var _a, _b, _c, _d, _e;
|
|
187
|
+
var _a, _b, _c, _d, _e, _f;
|
|
177
188
|
let beforeFlag = false;
|
|
178
189
|
let action = null;
|
|
179
190
|
let targetImages = [];
|
|
@@ -194,14 +205,17 @@ function setActions(traceRawResult, traceModel, tracePath, stackData) {
|
|
|
194
205
|
else if (entry.type == "event" || entry.type == "console") {
|
|
195
206
|
(_a = traceModel.events) === null || _a === void 0 ? void 0 : _a.push(entry);
|
|
196
207
|
}
|
|
208
|
+
else if (entry.type === "stdout" || entry.type === "stderr") {
|
|
209
|
+
(_b = traceModel === null || traceModel === void 0 ? void 0 : traceModel.stdio) === null || _b === void 0 ? void 0 : _b.push(entry);
|
|
210
|
+
}
|
|
197
211
|
else if (entry.type == "screencast-frame") {
|
|
198
|
-
let page = (
|
|
212
|
+
let page = (_c = traceModel.pages) === null || _c === void 0 ? void 0 : _c.find(p => p.pageId === entry.pageId);
|
|
199
213
|
if (!page) {
|
|
200
214
|
page = {
|
|
201
215
|
pageId: entry.pageId,
|
|
202
216
|
screencastFrames: [],
|
|
203
217
|
};
|
|
204
|
-
(
|
|
218
|
+
(_d = traceModel.pages) === null || _d === void 0 ? void 0 : _d.push(page);
|
|
205
219
|
}
|
|
206
220
|
targetImages.push(entry.sha1);
|
|
207
221
|
page.screencastFrames.push(entry);
|
|
@@ -226,7 +240,7 @@ function setActions(traceRawResult, traceModel, tracePath, stackData) {
|
|
|
226
240
|
}
|
|
227
241
|
if (beforeFlag && action != null && action.callId == entry.callId) {
|
|
228
242
|
if (entry.type == "log") {
|
|
229
|
-
(
|
|
243
|
+
(_e = action.log) === null || _e === void 0 ? void 0 : _e.push({
|
|
230
244
|
time: entry.time,
|
|
231
245
|
message: entry.message
|
|
232
246
|
});
|
|
@@ -237,12 +251,15 @@ function setActions(traceRawResult, traceModel, tracePath, stackData) {
|
|
|
237
251
|
action.result = entry.result;
|
|
238
252
|
action.error = entry.error;
|
|
239
253
|
action.afterSnapshot = entry.afterSnapshot;
|
|
240
|
-
(
|
|
254
|
+
(_f = traceModel.actions) === null || _f === void 0 ? void 0 : _f.push(action);
|
|
241
255
|
}
|
|
242
256
|
}
|
|
243
257
|
}
|
|
244
258
|
}
|
|
245
259
|
traceModel.endTime = action === null || action === void 0 ? void 0 : action.endTime;
|
|
260
|
+
if (traceModel.endTime != null && traceModel.startTime) {
|
|
261
|
+
traceModel.duration = Number((traceModel.endTime - traceModel.startTime).toFixed(3));
|
|
262
|
+
}
|
|
246
263
|
yield extractResources(tracePath, targetImages);
|
|
247
264
|
});
|
|
248
265
|
}
|
|
@@ -286,7 +303,8 @@ function prepareTraceModel(tracePath, logLevel) {
|
|
|
286
303
|
events: [],
|
|
287
304
|
resources: [],
|
|
288
305
|
errors: [],
|
|
289
|
-
pages: []
|
|
306
|
+
pages: [],
|
|
307
|
+
stdio: []
|
|
290
308
|
};
|
|
291
309
|
if (logLevel == runnerConfig_1.LogLevel.DEBUG) {
|
|
292
310
|
fs_1.default.writeFileSync(path_1.default.join(path_1.default.dirname(tracePath), "trace-raw-data.json"), JSON.stringify(traceRawResult, null, 2), "utf-8");
|
package/package.json
CHANGED
|
@@ -1,19 +1,22 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@apica-io/asm-playwright-runner",
|
|
3
|
-
"version": "1.0.0-dev.
|
|
3
|
+
"version": "1.0.0-dev.3",
|
|
4
4
|
"description": "CLI wrapper for Playwright collections or scripts with dynamic actions, config, and test result models.",
|
|
5
|
-
"main": "dist/cli.js",
|
|
5
|
+
"main": "dist/cli/index.js",
|
|
6
6
|
"bin": {
|
|
7
|
-
"asm-playwright-runner": "./dist/cli.js"
|
|
7
|
+
"asm-playwright-runner": "./dist/cli/index.js"
|
|
8
8
|
},
|
|
9
9
|
"scripts": {
|
|
10
10
|
"build": "tsc",
|
|
11
11
|
"start": "ts-node src/cli/ index.ts",
|
|
12
12
|
"dev": "ts-node-dev --respawn src/cli/index.ts",
|
|
13
|
+
|
|
13
14
|
"test:playwright-script": "ts-node src/cli samples/playwright-script.spec.ts --timeout 10000 --browser chromium --headless -v -r result1 -l debug",
|
|
14
15
|
"test:playwright/test-script": "ts-node src/cli samples/playwright-test-script.spec.ts --browser chromium --headless -r result2 -l debug",
|
|
15
16
|
"test:playwright-multi-script": "ts-node src/cli samples/playwright-multi-script.spec.ts --browser chromium --headless -v -r result3 -l debug",
|
|
17
|
+
|
|
16
18
|
"test:betsson-script": "ts-node src/cli samples/betsson.spec.ts --browser chromium -r result-betsson --headless false -l debug --extraHTTPHeaders {\\\"x-obg-bypass-fabric\\\":\\\"1\\\",\\\"x-obg-experiments\\\":\\\"b1ccAR1gW0f8\\\"}",
|
|
19
|
+
|
|
17
20
|
"test:playwright-json": "ts-node src/cli samples/example.json --browser chromium --headless -v -r results3",
|
|
18
21
|
"test:google": "ts-node src/cli samples/google.json --browser chromium --headless -v -r playwright-multi-script",
|
|
19
22
|
"test:google-firefox": "ts-node src/cli samples/google.json --browser firefox --headless -v -r playwright-multi-script"
|
|
@@ -30,12 +33,10 @@
|
|
|
30
33
|
"license": "ISC",
|
|
31
34
|
"dependencies": {
|
|
32
35
|
"commander": "^11.0.0",
|
|
33
|
-
"playwright": "^1.60.0",
|
|
34
|
-
"playwright-core": "^1.59.1",
|
|
35
36
|
"log4js": "^6.3.0"
|
|
36
37
|
},
|
|
37
38
|
"devDependencies": {
|
|
38
|
-
"@playwright/test": "^1.
|
|
39
|
+
"@playwright/test": "^1.60.0",
|
|
39
40
|
"@types/leaflet": "^1.9.15",
|
|
40
41
|
"@types/node": "^25.6.2",
|
|
41
42
|
"ts-node": "^10.9.2",
|
|
@@ -48,7 +48,7 @@ test.describe('Playwright home page', () => {
|
|
|
48
48
|
})
|
|
49
49
|
|
|
50
50
|
test.describe('has Open Graph tags', () => {
|
|
51
|
-
const tags = ['description', '
|
|
51
|
+
const tags = ['description', '1title', '2url']
|
|
52
52
|
|
|
53
53
|
// You can create tests from an array, by calling "test()" in a loop
|
|
54
54
|
tags.forEach((tag) => {
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {expect, Page} from "playwright/test";
|
|
1
|
+
import {expect, Page} from "playwright/test";
|
|
2
2
|
|
|
3
|
-
export default async function example(page: Page) {
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
export default async function example(page: Page) {
|
|
4
|
+
await page.goto("https://playwright.dev/");
|
|
5
|
+
await expect(page).toHaveTitle(/Playwright/);
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
}
|
|
7
|
+
await page.getByRole("link", { name: "Get started11" }).click();
|
|
8
|
+
await expect(page.getByRole("heading", { name: "Installation" })).toBeVisible();
|
|
9
|
+
}
|
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
import { test, expect } from '@playwright/test';
|
|
2
2
|
|
|
3
|
+
/*
|
|
3
4
|
test('has title', async ({ page }) => {
|
|
4
5
|
await page.goto('https://playwright.dev/');
|
|
5
6
|
|
|
6
7
|
// Expect a title "to contain" a substring.
|
|
7
8
|
await expect(page).toHaveTitle(/Playwright/);
|
|
8
9
|
});
|
|
10
|
+
*/
|
|
9
11
|
|
|
10
12
|
test('get started link', async ({ page }) => {
|
|
11
13
|
await page.goto('https://playwright.dev/');
|
|
12
14
|
|
|
13
15
|
// Click the get started link.
|
|
14
|
-
await page.getByRole('link', { name: 'Get
|
|
16
|
+
await page.getByRole('link', { name: 'Get started11' }).click();
|
|
15
17
|
|
|
16
18
|
// Expects page to have a heading with the name of Installation.
|
|
17
19
|
await expect(page.getByRole('heading', { name: 'Installation' })).toBeVisible();
|
package/src/lib/parser.ts
CHANGED
|
@@ -107,13 +107,22 @@ async function extractResources(
|
|
|
107
107
|
});
|
|
108
108
|
});
|
|
109
109
|
|
|
110
|
+
const errorContext = path.join(baseDir, "error-context.md");
|
|
111
|
+
|
|
112
|
+
if (fs.existsSync(errorContext)) {
|
|
113
|
+
fs.copyFileSync(
|
|
114
|
+
errorContext,
|
|
115
|
+
path.join(sourceDir, "error-context.md"));
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
|
|
110
119
|
await Promise.all([...imagePromises, ...sourcePromises]);
|
|
111
120
|
}
|
|
112
121
|
|
|
113
122
|
export async function zipResources(outputZipPath: string, screenshotsDir: string, sourceDir: string) {
|
|
114
123
|
return new Promise<void>((resolve, reject) => {
|
|
115
124
|
const output = fs.createWriteStream(outputZipPath);
|
|
116
|
-
const archive = archiver("zip", {
|
|
125
|
+
const archive = archiver("zip", {zlib: {level: 9}});
|
|
117
126
|
|
|
118
127
|
output.on("close", resolve);
|
|
119
128
|
archive.on("error", reject);
|
|
@@ -133,7 +142,7 @@ export async function zipResources(outputZipPath: string, screenshotsDir: string
|
|
|
133
142
|
}
|
|
134
143
|
|
|
135
144
|
export async function setHookActions(traceRawResult: string[]): Promise<TraceModel> {
|
|
136
|
-
const hookModel: TraceModel = {actions: [], stdio: []};
|
|
145
|
+
const hookModel: TraceModel = {actions: [], stdio: [], errors: []};
|
|
137
146
|
const hookActions: Record<string, HookAction> = {};
|
|
138
147
|
|
|
139
148
|
for (const [index, row] of traceRawResult.entries()) {
|
|
@@ -154,7 +163,7 @@ export async function setHookActions(traceRawResult: string[]): Promise<TraceMod
|
|
|
154
163
|
testTimeout: entry.testTimeout,
|
|
155
164
|
});
|
|
156
165
|
continue;
|
|
157
|
-
} else if (entry.type === "stdout") {
|
|
166
|
+
} else if (entry.type === "stdout" || entry.type === "stderr") {
|
|
158
167
|
hookModel?.stdio?.push(entry)
|
|
159
168
|
} else if (entry.type === "before") {
|
|
160
169
|
const action: HookAction = {
|
|
@@ -176,11 +185,17 @@ export async function setHookActions(traceRawResult: string[]): Promise<TraceMod
|
|
|
176
185
|
Object.assign(hookActions[entry.callId], {
|
|
177
186
|
endTime: entry.endTime,
|
|
178
187
|
annotations: entry.annotations,
|
|
188
|
+
error: entry.error,
|
|
179
189
|
});
|
|
190
|
+
} else if (entry.type == "error") {
|
|
191
|
+
hookModel.errors?.push(entry);
|
|
180
192
|
}
|
|
181
193
|
|
|
182
194
|
if (index === (traceRawResult.length - 1) && entry.type === "after") {
|
|
183
195
|
hookModel.endTime = entry.endTime;
|
|
196
|
+
if (hookModel.endTime != null && hookModel.startTime) {
|
|
197
|
+
hookModel.duration = Number((hookModel.endTime - hookModel.startTime).toFixed(3));
|
|
198
|
+
}
|
|
184
199
|
}
|
|
185
200
|
}
|
|
186
201
|
|
|
@@ -208,6 +223,8 @@ export async function setActions(traceRawResult: string[], traceModel: TraceMode
|
|
|
208
223
|
traceModel.contextId = entry.contextId;
|
|
209
224
|
} else if (entry.type == "event" || entry.type == "console") {
|
|
210
225
|
traceModel.events?.push(entry);
|
|
226
|
+
} else if (entry.type === "stdout" || entry.type === "stderr") {
|
|
227
|
+
traceModel?.stdio?.push(entry)
|
|
211
228
|
} else if (entry.type == "screencast-frame") {
|
|
212
229
|
let page = traceModel.pages?.find(
|
|
213
230
|
p => p.pageId === entry.pageId
|
|
@@ -265,6 +282,9 @@ export async function setActions(traceRawResult: string[], traceModel: TraceMode
|
|
|
265
282
|
}
|
|
266
283
|
|
|
267
284
|
traceModel.endTime = action?.endTime
|
|
285
|
+
if (traceModel.endTime != null && traceModel.startTime) {
|
|
286
|
+
traceModel.duration = Number((traceModel.endTime - traceModel.startTime).toFixed(3));
|
|
287
|
+
}
|
|
268
288
|
await extractResources(tracePath, targetImages)
|
|
269
289
|
}
|
|
270
290
|
|
|
@@ -309,7 +329,8 @@ export async function prepareTraceModel(tracePath: string, logLevel: LogLevel |
|
|
|
309
329
|
events: [],
|
|
310
330
|
resources: [],
|
|
311
331
|
errors: [],
|
|
312
|
-
pages: []
|
|
332
|
+
pages: [],
|
|
333
|
+
stdio: []
|
|
313
334
|
};
|
|
314
335
|
|
|
315
336
|
if (logLevel == LogLevel.DEBUG) {
|
package/src/model/traceModel.ts
CHANGED
|
@@ -3,6 +3,7 @@ export interface TraceModel {
|
|
|
3
3
|
browserName?: string;
|
|
4
4
|
contextId?: string;
|
|
5
5
|
endTime?: number;
|
|
6
|
+
duration?: number;
|
|
6
7
|
events?: Event[];
|
|
7
8
|
hasSource?: boolean;
|
|
8
9
|
options?: BrowserContextOptions;
|
|
@@ -20,7 +21,7 @@ export interface TraceModel {
|
|
|
20
21
|
// this is for hook test model
|
|
21
22
|
testTimeout?: number
|
|
22
23
|
|
|
23
|
-
errors?: [];
|
|
24
|
+
errors?: Record<string, any>[];
|
|
24
25
|
}
|
|
25
26
|
|
|
26
27
|
export interface Resource {
|