Skip to content

Commit

Permalink
fix: exception if no baseline is missing (#81)
Browse files Browse the repository at this point in the history
* fix: exception if no baseline is missing
  • Loading branch information
pashidlos authored Mar 8, 2021
1 parent f396875 commit 05e7e20
Show file tree
Hide file tree
Showing 9 changed files with 220 additions and 95 deletions.
26 changes: 26 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
name: CI

on:
push:
branches: [master]
pull_request:
branches: [master]

jobs:
build:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2

- name: Setup Node.js environment
uses: actions/[email protected]

- name: Install npm dependencies
run: npm ci

- name: Build
run: npm run build

- name: Unit tests
run: npm run test
13 changes: 9 additions & 4 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,19 @@ jobs:
uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Setup Node.js
uses: actions/setup-node@v1
with:
node-version: 12

- name: Setup Node.js environment
uses: actions/[email protected]

- name: Install dependencies
run: npm ci

- name: Build
run: npm run build

- name: Unit tests
run: npm run test

- name: Release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Expand Down
4 changes: 2 additions & 2 deletions cypress.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@
"visualRegressionTracker": {
"apiUrl": "http://localhost:4200",
"apiKey": "5H90NFWM6BMWWDMWKG8T11DWW22Y",
"project": "cb537710-9d84-4318-b450-2953c5d98361",
"project": "e999e73d-d683-4311-928c-d6f8fe82e4f8",
"branchName": "master",
"enableSoftAssert": false,
"enableSoftAssert": true,
"ciBuildId": null
}
}
Expand Down
84 changes: 84 additions & 0 deletions cypress/integration/regression.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/// <reference types="cypress" />
/// <reference types="../../dist" />

import { TestRunResponse, TestStatus } from "@visual-regression-tracker/sdk-js";
import * as utils from "../../lib/utils";

const testRunResponce: TestRunResponse = {
id: "someId",
imageName: "imageName",
diffName: "diffName",
baselineName: "baselineName",
diffPercent: 1.11,
diffTollerancePercent: 2.22,
pixelMisMatchCount: 3,
status: TestStatus.unresolved,
url: "url",
merge: true,
};

describe("Regression suite", () => {
describe("trackWithRetry", () => {
it("should stop on condition", () => {
utils.trackWithRetry(
cy.stub().as("trackFn").resolves(testRunResponce),
cy.stub().as("shouldStopFn").returns(true),
cy.stub().as("checkResult")
);

cy.get("@trackFn").should("have.callCount", 1);
cy.get("@shouldStopFn").should("have.callCount", 1);
cy.get("@checkResult").should("have.callCount", 1);
});

it("should stop on default retry limit", () => {
utils.trackWithRetry(
cy.stub().as("trackFn").resolves(testRunResponce),
cy.stub().as("shouldStopFn").returns(false),
cy.stub().as("checkResult")
);

cy.get("@trackFn").should("have.been.calledThrice");
cy.get("@shouldStopFn").should("have.been.calledTwice");
cy.get("@checkResult").should("have.been.calledOnce");
});

it("should stop on custom retry limit", () => {
utils.trackWithRetry(
cy.stub().as("trackFn").resolves(testRunResponce),
cy.stub().as("shouldStopFn").returns(false),
cy.stub().as("checkResult"),
{
retryLimit: 5,
}
);

cy.get("@trackFn").should("have.callCount", 6);
});
});

describe("shouldStopRetry", () => {
it("should continue", () => {
expect(
utils.shouldStopRetry({
...testRunResponce,
status: TestStatus.unresolved,
})
).to.be.false;
});
it("should stop", () => {
expect(
utils.shouldStopRetry({
...testRunResponce,
status: TestStatus.ok,
})
).to.be.true;
expect(
utils.shouldStopRetry({
...testRunResponce,
status: TestStatus.new,
})
).to.be.true;
});
});
});
11 changes: 10 additions & 1 deletion cypress/integration/retry.spec.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,21 @@
/* global cy */

before(() => {
cy.vrtStart();
});

after(() => {
cy.vrtStop();
});

context("Visual Regression Tracker2", () => {
beforeEach(() => {
cy.viewport("macbook-16");
cy.visit("https://jestjs.io/");
});

it("example2", () => {
cy.get(".jest-card-run").vrtTrack("card");
cy.wait(3000);
cy.get(".jest-card-run").vrtTrack("card1");
});
});
8 changes: 0 additions & 8 deletions cypress/support/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,3 @@ import "./commands";

/// <reference types="cypress" />
/// <reference path="../../dist/index.d.ts" />

before(() => {
cy.vrtStart();
});

after(() => {
cy.vrtStop();
});
88 changes: 9 additions & 79 deletions lib/commands.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
/* global Cypress, cy */

import { TestRunResponse, TestStatus } from "@visual-regression-tracker/sdk-js";

const log = (message: string) =>
Cypress.log({
name: "Visual Regression Tracker",
displayName: "VRT",
message,
});
import {
log,
shouldStopRetry,
checkResult,
trackImage,
trackWithRetry,
} from "./utils";

export const addVrtStartCommand = () => {
Cypress.Commands.add(
Expand Down Expand Up @@ -45,75 +43,6 @@ export const addVrtStopCommand = () => {
);
};

const trackWithRetry = (
trackFn: () => Cypress.Chainable<unknown>,
shouldStopFn: (result: any) => boolean,
options: {
retryLimit: number;
} = {
retryLimit: 2,
}
) => {
trackFn().then((result) => {
if (shouldStopFn(result)) {
return;
}

if (options.retryLimit <= 0) {
cy.task("VRT_PROCESS_ERROR_RESULT", result, { log: false });
return;
}

log(`Diff found... Remaining retry attempts **${options.retryLimit}**`);
trackWithRetry(trackFn, shouldStopFn, {
retryLimit: options.retryLimit - 1,
});
});
};

const shouldStopRetry = (result: TestRunResponse) =>
result?.status === TestStatus.ok ||
// no need to retry if no baseline
result?.status === TestStatus.new;

const trackImage = (
subject: any,
name: string,
options: any
): Cypress.Chainable<unknown> => {
let imagePath: string;
let pixelRatio: number;
const target = subject ? cy.wrap(subject) : cy;

return target
.screenshot(name, {
...options,
onAfterScreenshot: (el, props) => {
imagePath = props.path;
pixelRatio = props.pixelRatio;
return options?.onAfterScreenshot;
},
})
.then(() => log(`tracking ${name}`))
.then(() => cy.task("ENCODE_IMAGE", { imagePath }, { log: false }))
.then((imageBase64) =>
cy.task(
"VRT_TRACK_IMAGE",
{
name,
imageBase64,
browser: Cypress.browser.name,
pixelRatio,
os: options?.os,
device: options?.device,
diffTollerancePercent: options?.diffTollerancePercent,
ignoreAreas: options?.ignoreAreas,
},
{ log: false }
)
);
};

export const addVrtTrackCommand = () =>
Cypress.Commands.add(
"vrtTrack",
Expand All @@ -123,7 +52,8 @@ export const addVrtTrackCommand = () =>
(subject, name, options) => {
trackWithRetry(
() => trackImage(subject, name, options),
(result) => shouldStopRetry(result as TestRunResponse),
(result) => shouldStopRetry(result),
(result) => checkResult(result),
options
);
}
Expand Down
79 changes: 79 additions & 0 deletions lib/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/* global Cypress, cy */

import { TestRunResponse, TestStatus } from "@visual-regression-tracker/sdk-js";

export const log = (message: string) =>
Cypress.log({
name: "Visual Regression Tracker",
displayName: "VRT",
message,
});

export const trackWithRetry = (
trackFn: () => Cypress.Chainable<TestRunResponse>,
shouldStopFn: (result: TestRunResponse) => boolean,
onStopFn: (result: TestRunResponse) => Cypress.Chainable<unknown>,
options: {
retryLimit: number;
} = {
retryLimit: 2,
}
): Cypress.Chainable<unknown> => {
return trackFn().then((result) => {
if (options.retryLimit <= 0 || shouldStopFn(result)) {
onStopFn(result);
return;
}

log(`Diff found... Remaining retry attempts **${options.retryLimit}**`);
return trackWithRetry(trackFn, shouldStopFn, onStopFn, {
retryLimit: options.retryLimit - 1,
});
});
};

export const checkResult = (result: TestRunResponse) =>
cy.task("VRT_PROCESS_ERROR_RESULT", result, { log: false });

export const shouldStopRetry = (result: TestRunResponse) =>
result?.status === TestStatus.ok ||
// no need to retry if no baseline
result?.status === TestStatus.new;

export const trackImage = (
subject: any,
name: string,
options: any
): Cypress.Chainable<TestRunResponse> => {
let imagePath: string;
let pixelRatio: number;
const target = subject ? cy.wrap(subject) : cy;

return target
.screenshot(name, {
...options,
onAfterScreenshot: (el, props) => {
imagePath = props.path;
pixelRatio = props.pixelRatio;
return options?.onAfterScreenshot;
},
})
.then(() => log(`tracking ${name}`))
.then(() => cy.task("ENCODE_IMAGE", { imagePath }, { log: false }))
.then((imageBase64) =>
cy.task(
"VRT_TRACK_IMAGE",
{
name,
imageBase64,
browser: Cypress.browser.name,
pixelRatio,
os: options?.os,
device: options?.device,
diffTollerancePercent: options?.diffTollerancePercent,
ignoreAreas: options?.ignoreAreas,
},
{ log: false }
)
);
};
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"version": "4.7.0",
"description": "Visual Regression Tracker integration plugin",
"scripts": {
"test": "jest",
"test": "cypress run --spec 'cypress/integration/regression.spec.ts'",
"build": "tsc",
"semantic-release": "semantic-release"
},
Expand Down

0 comments on commit 05e7e20

Please sign in to comment.