Skip to content

Commit

Permalink
feat: simplify playwright setup
Browse files Browse the repository at this point in the history
  • Loading branch information
gregberge committed Dec 26, 2023
1 parent 672a6e0 commit 1dc45b9
Show file tree
Hide file tree
Showing 7 changed files with 55 additions and 91 deletions.
78 changes: 16 additions & 62 deletions packages/playwright/docs/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ slug: /playwright

Improve test debugging and boost your visual testing capabilities by combining Argos with your [Playwright](https://playwright.dev/) tests.

## Introduction
## Features

### Test debugging

Expand All @@ -29,62 +29,7 @@ Argos presents a significant advantage over traditional Playwright visual tests

## Get started

### 1. Install package

```
npm install --save-dev @argos-ci/playwright
```

### 2. Configure Argos

The Argos reporter seamlessly uploads screenshots and traces to Argos in real-time.

Install Argos in your Playwright config:

```typescript
import { defineConfig } from "@playwright/test";

export default defineConfig({
// ... other configuration

// Setup recording option to enable test debugging features
use: {
// Setting to capture screenshot only when a test fails
screenshot: "only-on-failure",
// Setting to retain traces only when a test fails
trace: "retain-on-failure",
},

// Add Argos reporter only when it runs on CI
reporter: process.env.CI
? [["list"], ["@argos-ci/playwright/reporter"]]
: "list",
});
```

Playwright's [recording options](https://playwright.dev/docs/test-use-options#recording-options) facilitate the automated capture of screenshots upon test failures. Notably, these captured screenshots and traces are then automatically uploaded to Argos.

### 3. Take screenshots

`argosScreenshot` command stabilizes the UI before capturing the screenshot.

```js
import { test } from "@playwright/test";
import { argosScreenshot } from "@argos-ci/playwright";

test.describe("Homepage", () => {
test("take screenshot", async ({ page }) => {
await page.goto(TEST_URL);
await argosScreenshot(page, "homepage");
});
});
```

### 4. Setup your CI

Execute your Playwright tests in the usual manner. Screenshots will be auto-uploaded.

> Note: For CI platforms other than GitHub Actions, ensure `ARGOS_TOKEN` is set as an environment variable.
Please refer to our [Quickstart guide](/quickstart/playwright) to get started with Argos and Playwright.

## API Overview

Expand Down Expand Up @@ -114,6 +59,7 @@ export default defineConfig({
[
"@argos-ci/playwright/reporter",
{
uploadToArgos: !!process.env.CI,
buildName: "custom-build-name",
} as ArgosReporterOptions,
],
Expand Down Expand Up @@ -150,18 +96,25 @@ import { defineConfig } from "@playwright/test";
export default defineConfig({
// ... other configuration

// Add Argos reporter.
reporter: [
["list"],
[
"@argos-ci/playwright/reporter",
{
// Upload artefacts to Argos on CI.
uploadToArgos: !!process.env.CI,
},
],
],

// Setup recording option to enable test debugging features
use: {
// Setting to capture screenshot only when a test fails
screenshot: "only-on-failure",
// Setting to retain traces only when a test fails
trace: "retain-on-failure",
},

// Add Argos reporter only when it runs on CI
reporter: process.env.CI
? [["list"], ["@argos-ci/playwright/reporter"]]
: "list",
});
```

Expand All @@ -172,6 +125,7 @@ export default defineConfig({

## Additional Resources

- [Quickstart with Argos + Playwright](/quickstart/playwright)
- [Argos + Playwright example](https://github.com/argos-ci/argos/tree/main/examples/playwright)
- [@argos-ci/playwright on GitHub](https://github.com/argos-ci/argos-javascript/tree/main/packages/playwright)
- [@argos-ci/playwright on npm](https://www.npmjs.com/package/@argos-ci/playwright)
5 changes: 3 additions & 2 deletions packages/playwright/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@
"dependencies": {
"@argos-ci/browser": "workspace:*",
"@argos-ci/core": "workspace:*",
"@argos-ci/util": "workspace:*"
"@argos-ci/util": "workspace:*",
"chalk": "^5.3.0"
},
"devDependencies": {
"@argos-ci/cli": "workspace:*",
Expand All @@ -56,6 +57,6 @@
"prebuild": "rm -rf dist",
"build": "rollup -c",
"test": "pnpm exec playwright test",
"e2e": "WITH_ARGOS_REPORTER=true pnpm run test"
"e2e": "pnpm run test"
}
}
25 changes: 10 additions & 15 deletions packages/playwright/playwright.config.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import { PlaywrightTestConfig, defineConfig, devices } from "@playwright/test";
import { defineConfig, devices } from "@playwright/test";
import type { ArgosReporterOptions } from "@argos-ci/playwright/reporter";

const defaultReporters: PlaywrightTestConfig["reporter"] = [["list"]];

export default defineConfig({
use: {
screenshot: "only-on-failure",
Expand All @@ -14,16 +12,13 @@ export default defineConfig({
use: { ...devices["Desktop Chrome"] },
},
],
reporter:
process.env.WITH_ARGOS_REPORTER === "true"
? [
...defaultReporters,
[
"@argos-ci/playwright/reporter",
{
buildName: `argos-playwright-e2e-node-${process.env.NODE_VERSION}-${process.env.OS}`,
} as ArgosReporterOptions,
],
]
: defaultReporters,
reporter: [
["list"],
[
"@argos-ci/playwright/reporter",
{
buildName: `argos-playwright-e2e-node-${process.env.NODE_VERSION}-${process.env.OS}`,
} as ArgosReporterOptions,
],
],
});
8 changes: 4 additions & 4 deletions packages/playwright/src/attachment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ export function getAttachmentFilename(name: string) {

export type Attachment = TestResult["attachments"][number];
export type ArgosScreenshotAttachment = Attachment & {
body: Buffer;
path: string;
};
export type ArgosMetadataAttachment = Attachment & {
body: Buffer;
path: string;
};
export type AutomaticScreenshotAttachment = Attachment & {
name: "screenshot";
Expand All @@ -50,7 +50,7 @@ export function checkIsArgosScreenshot(
return (
attachment.name.startsWith("argos/") &&
attachment.contentType === "image/png" &&
Boolean(attachment.body)
Boolean(attachment.path)
);
}

Expand All @@ -60,7 +60,7 @@ export function checkIsArgosScreenshotMetadata(
return (
attachment.name.startsWith("argos/") &&
attachment.contentType === "application/json" &&
Boolean(attachment.body)
Boolean(attachment.path)
);
}

Expand Down
2 changes: 1 addition & 1 deletion packages/playwright/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ export async function argosScreenshot(

const metadata = await collectMetadata(testInfo);
const screenshotPath = useArgosReporter
? null
? testInfo!.outputPath("argos", `${name}.png`)
: resolve(screenshotFolder, `${name}.png`);

if (screenshotPath) {
Expand Down
17 changes: 14 additions & 3 deletions packages/playwright/src/reporter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import type {
TestCase,
TestResult,
} from "@playwright/test/reporter";
import chalk from "chalk";
import { readConfig, upload, UploadParameters } from "@argos-ci/core";
import { randomBytes } from "node:crypto";
import { copyFile, mkdir, writeFile } from "node:fs/promises";
Expand All @@ -27,7 +28,12 @@ async function createTempDirectory() {
return path;
}

export type ArgosReporterOptions = Omit<UploadParameters, "files" | "root">;
export type ArgosReporterOptions = Omit<UploadParameters, "files" | "root"> & {
/**
* If `true`, the report will be uploaded to Argos.
*/
uploadToArgos?: boolean;
};

const getParallelFromConfig = (
config: FullConfig,
Expand All @@ -50,9 +56,11 @@ class ArgosReporter implements Reporter {
uploadDir!: string;
config: ArgosReporterOptions;
playwrightConfig!: FullConfig;
uploadToArgos: boolean;

constructor(config: ArgosReporterOptions) {
this.config = config;
this.uploadToArgos = config.uploadToArgos ?? false;
}

async writeFile(path: string, body: Buffer | string) {
Expand Down Expand Up @@ -89,7 +97,7 @@ class ArgosReporter implements Reporter {
this.uploadDir,
getAttachmentFilename(attachment.name),
);
await this.writeFile(path, attachment.body);
await copyFile(attachment.path, path);
return;
}

Expand All @@ -111,15 +119,18 @@ class ArgosReporter implements Reporter {
}

async onEnd(_result: FullResult) {
if (!this.uploadToArgos) return;

const parallel = getParallelFromConfig(this.playwrightConfig);

try {
await upload({
const res = await upload({
files: ["**/*.png"],
root: this.uploadDir,
parallel: parallel ?? undefined,
...this.config,
});
console.log(chalk.green(`✅ Argos build created: ${res.build.url}`));
} catch (error) {
console.error(error);
return { status: "failed" as const };
Expand Down
11 changes: 7 additions & 4 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 1dc45b9

Please sign in to comment.