@argos-ci/playwright 1.0.1 → 1.2.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.
package/dist/index.mjs CHANGED
@@ -58,6 +58,8 @@ async function getTestMetadataFromTestInfo(testInfo) {
58
58
  id: testInfo.testId,
59
59
  title: testInfo.title,
60
60
  titlePath: testInfo.titlePath,
61
+ retry: testInfo.retry,
62
+ retries: testInfo.project.retries,
61
63
  location: {
62
64
  file: repositoryPath ? relative(repositoryPath, testInfo.file) : testInfo.file,
63
65
  line: testInfo.line,
@@ -5,9 +5,11 @@ type ArgosReporterOptions = Omit<UploadParameters, "files" | "root">;
5
5
  declare class ArgosReporter implements Reporter {
6
6
  uploadDir: string;
7
7
  config: ArgosReporterOptions;
8
+ playwrightConfig: FullConfig;
8
9
  constructor(config: ArgosReporterOptions);
9
10
  writeFile(path: string, body: Buffer | string): Promise<void>;
10
- onBegin(_config: FullConfig, _suite: Suite): Promise<void>;
11
+ getAutomaticScreenshotName(test: TestCase, result: TestResult): string;
12
+ onBegin(config: FullConfig, _suite: Suite): Promise<void>;
11
13
  onTestEnd(test: TestCase, result: TestResult): Promise<void>;
12
14
  onEnd(_result: FullResult): Promise<{
13
15
  status: "failed";
package/dist/reporter.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { upload } from '@argos-ci/core';
1
+ import { upload, readConfig } from '@argos-ci/core';
2
2
  import { randomBytes } from 'node:crypto';
3
3
  import { mkdir, writeFile, copyFile } from 'node:fs/promises';
4
4
  import { tmpdir } from 'node:os';
@@ -18,6 +18,15 @@ function getAttachementFilename(name) {
18
18
  }
19
19
  throw new Error(`Unknown attachment name: ${name}`);
20
20
  }
21
+ function checkIsTrace(attachment) {
22
+ return attachment.name === "trace" && attachment.contentType === "application/zip" && Boolean(attachment.path);
23
+ }
24
+ function checkIsArgosScreenshot(attachment) {
25
+ return attachment.name.startsWith("argos/") && attachment.contentType === "image/png" && Boolean(attachment.body);
26
+ }
27
+ function checkIsAutomaticScreenshot(attachment) {
28
+ return attachment.name === "screenshot" && attachment.contentType === "image/png" && Boolean(attachment.path);
29
+ }
21
30
 
22
31
  const require = createRequire(import.meta.url);
23
32
  const tryResolve = (pkg)=>{
@@ -63,11 +72,13 @@ async function getLibraryMetadata() {
63
72
  };
64
73
  return metadata;
65
74
  }
66
- async function getTestMetadataFromTestCase(testCase) {
75
+ async function getTestMetadataFromTestCase(testCase, testResult) {
67
76
  const repositoryPath = await getGitRepositoryPath();
68
77
  const testMetadata = {
69
78
  title: testCase.title,
70
79
  titlePath: testCase.titlePath(),
80
+ retry: testResult.retry,
81
+ retries: testCase.retries,
71
82
  location: {
72
83
  file: repositoryPath ? relative(repositoryPath, testCase.location.file) : testCase.location.file,
73
84
  line: testCase.location.line,
@@ -76,10 +87,10 @@ async function getTestMetadataFromTestCase(testCase) {
76
87
  };
77
88
  return testMetadata;
78
89
  }
79
- async function getMetadataFromTestCase(testCase) {
90
+ async function getMetadataFromTestCase(testCase, testResult) {
80
91
  const [libMetadata, testMetadata] = await Promise.all([
81
92
  getLibraryMetadata(),
82
- getTestMetadataFromTestCase(testCase)
93
+ getTestMetadataFromTestCase(testCase, testResult)
83
94
  ]);
84
95
  const metadata = {
85
96
  test: testMetadata,
@@ -96,9 +107,22 @@ async function createTempDirectory() {
96
107
  });
97
108
  return path;
98
109
  }
110
+ const getParallelFromConfig = (config)=>{
111
+ if (!config.shard) return null;
112
+ if (config.shard.total === 1) return null;
113
+ const argosConfig = readConfig();
114
+ if (!argosConfig.parallelNonce) {
115
+ throw new Error("Playwright shard mode detected. Please specify ARGOS_PARALLEL_NONCE env variable. Read https://argos-ci.com/docs/parallel-testing");
116
+ }
117
+ return {
118
+ total: config.shard.total,
119
+ nonce: argosConfig.parallelNonce
120
+ };
121
+ };
99
122
  class ArgosReporter {
100
123
  uploadDir;
101
124
  config;
125
+ playwrightConfig;
102
126
  constructor(config){
103
127
  this.config = config;
104
128
  }
@@ -111,12 +135,19 @@ class ArgosReporter {
111
135
  }
112
136
  await writeFile(path, body);
113
137
  }
114
- async onBegin(_config, _suite) {
138
+ getAutomaticScreenshotName(test, result) {
139
+ let name = test.titlePath().join(" ");
140
+ name += result.retry > 0 ? ` #${result.retry + 1}` : "";
141
+ name += result.status === "failed" || result.status === "timedOut" ? " (failed)" : "";
142
+ return name;
143
+ }
144
+ async onBegin(config, _suite) {
145
+ this.playwrightConfig = config;
115
146
  this.uploadDir = await createTempDirectory();
116
147
  }
117
148
  async onTestEnd(test, result) {
118
149
  await Promise.all(result.attachments.map(async (attachment)=>{
119
- if (attachment.name.startsWith("argos/")) {
150
+ if (checkIsArgosScreenshot(attachment)) {
120
151
  if (!attachment.body) {
121
152
  throw new Error("Missing attachment body");
122
153
  }
@@ -125,24 +156,29 @@ class ArgosReporter {
125
156
  return;
126
157
  }
127
158
  // Error screenshots are sent to Argos
128
- if (attachment.name === "screenshot" && attachment.contentType === "image/png" && attachment.path) {
129
- const metadata = await getMetadataFromTestCase(test);
130
- const name = test.titlePath().join(" ");
131
- const path = join(this.uploadDir, result.status === "failed" || result.status === "timedOut" ? `${name} (failed).png` : `${name}.png`);
159
+ if (checkIsAutomaticScreenshot(attachment)) {
160
+ const trace = result.attachments.find(checkIsTrace) ?? null;
161
+ const metadata = await getMetadataFromTestCase(test, result);
162
+ const name = this.getAutomaticScreenshotName(test, result);
163
+ const path = join(this.uploadDir, `${name}.png`);
132
164
  await Promise.all([
133
165
  this.writeFile(path + ".argos.json", JSON.stringify(metadata)),
134
- copyFile(attachment.path, path)
166
+ copyFile(attachment.path, path),
167
+ trace ? copyFile(trace.path, path + ".pw-trace.zip") : null
135
168
  ]);
169
+ return;
136
170
  }
137
171
  }));
138
172
  }
139
173
  async onEnd(_result) {
174
+ const parallel = getParallelFromConfig(this.playwrightConfig);
140
175
  try {
141
176
  await upload({
142
177
  files: [
143
178
  "**/*.png"
144
179
  ],
145
180
  root: this.uploadDir,
181
+ parallel: parallel ?? undefined,
146
182
  ...this.config
147
183
  });
148
184
  } catch (error) {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@argos-ci/playwright",
3
3
  "description": "Visual testing solution to avoid visual regression. Playwright commands and utilities for Argos visual testing.",
4
- "version": "1.0.1",
4
+ "version": "1.2.0",
5
5
  "author": "Smooth Code",
6
6
  "license": "MIT",
7
7
  "repository": {
@@ -43,11 +43,11 @@
43
43
  },
44
44
  "dependencies": {
45
45
  "@argos-ci/browser": "1.0.0",
46
- "@argos-ci/core": "1.0.0",
47
- "@argos-ci/util": "1.0.0"
46
+ "@argos-ci/core": "1.2.0",
47
+ "@argos-ci/util": "1.1.0"
48
48
  },
49
49
  "devDependencies": {
50
- "@argos-ci/cli": "1.0.0",
50
+ "@argos-ci/cli": "1.0.2",
51
51
  "@argos-ci/playwright": "workspace:.",
52
52
  "@playwright/test": "^1.38.1",
53
53
  "@types/node": "^16.0.0"
@@ -58,5 +58,5 @@
58
58
  "test": "pnpm exec playwright test",
59
59
  "e2e": "WITH_ARGOS_REPORTER=true pnpm run test"
60
60
  },
61
- "gitHead": "772629785526eb051bc5f1ccabe927ff9781a7c4"
61
+ "gitHead": "47a939474ca0c0d55ca5360dcaa5f8912547ed76"
62
62
  }