Skip to content

Commit

Permalink
Merge pull request #23 from ergon/custom-pixelpact-hook
Browse files Browse the repository at this point in the history
Pixelpact Playwright client
  • Loading branch information
mloydd authored Oct 3, 2023
2 parents f40dc8b + a8fe72f commit 173096a
Show file tree
Hide file tree
Showing 34 changed files with 177 additions and 1,067 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build-docker-image.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ jobs:
- name: Build and push Docker image
uses: docker/build-push-action@v4
with:
context: pixelpact
context: server
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
6 changes: 3 additions & 3 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@ jobs:
with:
node-version: 19
cache: npm
cache-dependency-path: ./pixelpact/package-lock.json
cache-dependency-path: ./server/package-lock.json

- name: Install dependencies
run: npm ci
working-directory: ./pixelpact
working-directory: ./server

- name: Run Tests
run: npm run test
working-directory: ./pixelpact
working-directory: ./server
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
node_modules/
.idea
pixelpact/coverage
pixelpact/coverage
.direnv/
6 changes: 1 addition & 5 deletions bin/pre-commit
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,7 @@ if [[ "${TRACE-0}" == "1" ]]; then
set -o xtrace
fi

pushd pixelpact
npm run format
popd

pushd "example"
pushd server
npm run format
popd

Expand Down
12 changes: 12 additions & 0 deletions clients/js/playwright/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"name": "@pixelpact/playwright",
"version": "1.0.0",
"description": "Pixelpact Playwright helps to easily hook into Pixelpact Service",
"type": "module",
"author": "Ergon Informatik AG",
"license": "MIT",
"main": "src/index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
}
}
115 changes: 115 additions & 0 deletions clients/js/playwright/src/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
import { existsSync, mkdirSync } from "fs";
import fs from "fs/promises";

const appDir = process.env.PWD;
const MODE = process.env.PIXELPACT_MODE ?? "verify";
const SERVER_URL = process.env.PIXELPACT_SERVER_URL ?? "http://localhost:8888";
const FOLDER_PATH = process.env.PIXELPACT_FOLDER_PATH;
const folderPath = getFolderPath();

const expectedFileSuffix = "expected";
const actualFileSuffix = "actual";
const diffFileSuffix = "diff";

export async function toMatchVisually(page, testInfo, fileNamePrefix) {
if (!existsSync(folderPath)) {
mkdirSync(folderPath);
}

const session = await page.context().newCDPSession(page);
const mhtml = (
await session.send("Page.captureSnapshot", { format: "mhtml" })
).data;

if (MODE === "record") {
await recordReferenceImage(mhtml, page, fileNamePrefix);
} else if (MODE === "verify") {
await verfiy(page, testInfo, fileNamePrefix, mhtml);
} else {
throw Error("Unknown Mode!");
}
}

async function recordReferenceImage(mHtml, page, fileNamePrefix) {
const referenceFileName = composeFileName(fileNamePrefix, "expected");
const referenceFilePath = folderPath + referenceFileName;
const body = {
actualHtml: mHtml,
viewport: page.viewportSize(),
};

const response = await fetch(`${SERVER_URL}/render`, {
method: "post",
body: JSON.stringify(body),
headers: { "Content-Type": "application/json" },
});

const result = await response.json();
const referenceImage = Buffer.from(result.actual, "base64");
await fs.writeFile(referenceFilePath, referenceImage);
}

async function verfiy(page, testInfo, fileNamePrefix, mhtml) {
const referenceImage = await readReferenceImage(fileNamePrefix);
const body = {
actualHtml: mhtml,
expected: referenceImage.toString("base64"),
viewport: page.viewportSize(),
};

const response = await fetch(SERVER_URL + "/check", {
method: "post",
body: JSON.stringify(body),
headers: { "Content-Type": "application/json" },
});
const result = await response.json();

attachExpected(testInfo, fileNamePrefix);
await saveResult(result.actual, testInfo, fileNamePrefix, actualFileSuffix);
await saveResult(result.diff, testInfo, fileNamePrefix, diffFileSuffix);

if (result.numDiffPixels !== 0) {
throw Error(
"Actual Image does not match reference image! Pixeldiff: " +
result.numDiffPixels
);
}
}

async function saveResult(fileStr, testInfo, fileNamePrefix, fileNameSuffix) {
const fileName = composeFileName(fileNamePrefix, fileNameSuffix);
const filePath = folderPath + fileName;
await fs.writeFile(filePath, Buffer.from(fileStr, "base64"));
attachToTestInfo(testInfo, fileName, filePath);
}

function attachExpected(testInfo, fileNamePrefix) {
const fileName = composeFileName(fileNamePrefix, expectedFileSuffix);
const filePath = folderPath + fileName;
attachToTestInfo(testInfo, fileName, filePath);
}

function attachToTestInfo(testInfo, fileName, filePath) {
testInfo.attachments.push({
name: fileName,
contentType: "image/png",
path: filePath,
});
}

async function readReferenceImage(fileNamePrefix) {
const referenceFileName = composeFileName(fileNamePrefix, expectedFileSuffix);
const referenceFilePath = folderPath + referenceFileName;
return await fs.readFile(referenceFilePath);
}

function getFolderPath() {
if (FOLDER_PATH) {
return FOLDER_PATH.endsWith("/") ? FOLDER_PATH : `${FOLDER_PATH}/`;
}
return `${appDir}/pixelpact/`;
}

function composeFileName(fileNamePrefix, suffix) {
return `${fileNamePrefix}-${suffix}.png`;
}
Empty file added clients/jvm/.gitkeep
Empty file.
3 changes: 0 additions & 3 deletions example/example.css

This file was deleted.

13 changes: 0 additions & 13 deletions example/index.html

This file was deleted.

78 changes: 0 additions & 78 deletions example/index.js

This file was deleted.

Loading

0 comments on commit 173096a

Please sign in to comment.