From 1dc45b91a231a8bd12a56a36367f2f5bc5cebaa6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Greg=20Berg=C3=A9?= Date: Sun, 24 Dec 2023 14:18:56 +0400 Subject: [PATCH] feat: simplify playwright setup --- packages/playwright/docs/index.mdx | 78 +++++------------------- packages/playwright/package.json | 5 +- packages/playwright/playwright.config.ts | 25 +++----- packages/playwright/src/attachment.ts | 8 +-- packages/playwright/src/index.ts | 2 +- packages/playwright/src/reporter.ts | 17 +++++- pnpm-lock.yaml | 11 ++-- 7 files changed, 55 insertions(+), 91 deletions(-) diff --git a/packages/playwright/docs/index.mdx b/packages/playwright/docs/index.mdx index 3bb9771..fe2059e 100644 --- a/packages/playwright/docs/index.mdx +++ b/packages/playwright/docs/index.mdx @@ -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 @@ -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 @@ -114,6 +59,7 @@ export default defineConfig({ [ "@argos-ci/playwright/reporter", { + uploadToArgos: !!process.env.CI, buildName: "custom-build-name", } as ArgosReporterOptions, ], @@ -150,6 +96,18 @@ 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 @@ -157,11 +115,6 @@ export default defineConfig({ // 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", }); ``` @@ -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) diff --git a/packages/playwright/package.json b/packages/playwright/package.json index 0c8324e..f71e67f 100644 --- a/packages/playwright/package.json +++ b/packages/playwright/package.json @@ -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:*", @@ -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" } } diff --git a/packages/playwright/playwright.config.ts b/packages/playwright/playwright.config.ts index b8dbec4..da4aa61 100644 --- a/packages/playwright/playwright.config.ts +++ b/packages/playwright/playwright.config.ts @@ -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", @@ -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, + ], + ], }); diff --git a/packages/playwright/src/attachment.ts b/packages/playwright/src/attachment.ts index 21f1543..fe6f55b 100644 --- a/packages/playwright/src/attachment.ts +++ b/packages/playwright/src/attachment.ts @@ -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"; @@ -50,7 +50,7 @@ export function checkIsArgosScreenshot( return ( attachment.name.startsWith("argos/") && attachment.contentType === "image/png" && - Boolean(attachment.body) + Boolean(attachment.path) ); } @@ -60,7 +60,7 @@ export function checkIsArgosScreenshotMetadata( return ( attachment.name.startsWith("argos/") && attachment.contentType === "application/json" && - Boolean(attachment.body) + Boolean(attachment.path) ); } diff --git a/packages/playwright/src/index.ts b/packages/playwright/src/index.ts index b210a40..8f54c5f 100644 --- a/packages/playwright/src/index.ts +++ b/packages/playwright/src/index.ts @@ -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) { diff --git a/packages/playwright/src/reporter.ts b/packages/playwright/src/reporter.ts index 5578a89..de49ea7 100644 --- a/packages/playwright/src/reporter.ts +++ b/packages/playwright/src/reporter.ts @@ -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"; @@ -27,7 +28,12 @@ async function createTempDirectory() { return path; } -export type ArgosReporterOptions = Omit; +export type ArgosReporterOptions = Omit & { + /** + * If `true`, the report will be uploaded to Argos. + */ + uploadToArgos?: boolean; +}; const getParallelFromConfig = ( config: FullConfig, @@ -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) { @@ -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; } @@ -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 }; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 88b0ecf..a9eaa3d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -151,6 +151,9 @@ importers: '@argos-ci/util': specifier: workspace:* version: link:../util + chalk: + specifier: ^5.3.0 + version: 5.3.0 devDependencies: '@argos-ci/cli': specifier: workspace:* @@ -1175,7 +1178,7 @@ packages: resolution: {integrity: sha512-Bx1cRCZcVcWoz+atDQc4CSVzGuEgGJPOpIAXjQbBEA2cX5nqIBWdbye8eHu31En/F03aH9BhpNEJghs6wy4iTg==} engines: {node: '>=16.0.0'} dependencies: - chalk: 4.1.0 + chalk: 4.1.2 execa: 5.0.0 strong-log-transformer: 2.1.0 dev: true @@ -5504,7 +5507,7 @@ packages: hasBin: true dependencies: async: 3.2.4 - chalk: 4.1.0 + chalk: 4.1.2 filelist: 1.0.4 minimatch: 3.1.2 dev: true @@ -5645,7 +5648,7 @@ packages: resolution: {integrity: sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - chalk: 4.1.0 + chalk: 4.1.2 diff-sequences: 29.6.3 jest-get-type: 29.6.3 pretty-format: 29.7.0 @@ -7091,7 +7094,7 @@ packages: '@yarnpkg/parsers': 3.0.0-rc.46 '@zkochan/js-yaml': 0.0.6 axios: 1.5.1(debug@4.3.4) - chalk: 4.1.0 + chalk: 4.1.2 cli-cursor: 3.1.0 cli-spinners: 2.6.1 cliui: 8.0.1