Skip to content

[SDK-3090] Remote screenshotter service support #1

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Oct 28, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 7 additions & 46 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: CI
name: CI
on:
pull_request_target:
branches:
Expand All @@ -17,7 +17,7 @@ jobs:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: '16.x'
node-version: "16.x"
- name: Remove git auth
run: git config --unset http.https://github.com/.extraheader
- name: Generate yarn cache-key
Expand Down Expand Up @@ -52,7 +52,7 @@ jobs:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: '16.x'
node-version: "16.x"
- name: remove git auth
run: git config --unset http.https://github.com/.extraheader
- name: Configure Yarn cache
Expand All @@ -79,7 +79,7 @@ jobs:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: '16.x'
node-version: "16.x"
- name: remove git auth
run: git config --unset http.https://github.com/.extraheader
- name: Configure Yarn cache
Expand All @@ -102,41 +102,10 @@ jobs:
- name: Test component-testing
run: yarn test:ct:ci

test-integration-coverage:
name: test-integration-coverage
runs-on: ubuntu-latest
needs: cache
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: '16.x'
- name: remove git auth
run: git config --unset http.https://github.com/.extraheader
- name: Configure Yarn cache
uses: actions/cache@v3
with:
key: ${{ needs.cache.outputs.yarn-cache-key }}
path: |
~/.cache/Cypress
.yarn
node_modules
example/node_modules
- name: Install dependencies
run: yarn --immutable
- name: Test integration (with coverage)
uses: paambaati/codeclimate-action@93c6213edc13fcb74a684a39a32956ebf417dd1c
env:
CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }}
with:
coverageCommand: yarn test:integration:ci
coverageLocations: |
${{github.workspace}}/coverage/lcov.info:lcov

build-and-release:
name: build and release
runs-on: ubuntu-latest
needs: [cache, lint, test, test-integration-coverage]
needs: [cache, lint, test]
if: ${{ github.actor != 'dependabot[bot]' && github.ref == 'refs/heads/main' && github.event_name == 'push' }}
steps:
- uses: actions/checkout@v3
Expand All @@ -149,7 +118,7 @@ jobs:
git config --global user.email "$(git --no-pager log --format=format:'%ae' -n 1)"
- uses: actions/setup-node@v3
with:
node-version: '16.x'
node-version: "16.x"
- name: remove git auth
run: git config --unset http.https://github.com/.extraheader
- name: Configure Yarn cache
Expand All @@ -163,15 +132,7 @@ jobs:
example/node_modules
- name: Install dependencies
run: yarn --immutable
- name: Authenticate with Registry
run: |
yarn npm logout
echo "registry=http://registry.npmjs.org/" >> .npmrc
echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" >> .npmrc
npm whoami
env:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
- name: release package
- name: release to branch
if: ${{ success() }}
run: yarn release:ci
env:
Expand Down
8 changes: 6 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ cy.matchImage({
// maximum threshold above which the test should fail
// default: 0.01
maxDiffThreshold: 0.1,
// forces scale factor to be set as value "1"
// forces scale factor to be set as value "1"
// helps with screenshots being scaled 2x on high-density screens like Mac Retina
// default: true
forceDeviceScaleFactor: false,
Expand All @@ -195,6 +195,10 @@ cy.matchImage({
// instead of checking against the image from previous run
// default: undefined
matchAgainstPath: '/path/to/reference-image.png'
// pass the URL of an http service that accepts POST with a body like {"html"=>"<html>hello world</html>"} and
// responds with screenshotted image. This can be useful for eliminating rendering differences across operating systems.
// default: undefined
remoteScreenshotServiceUrl: 'https://example.com/screenshotter/render'
})
```

Expand All @@ -215,7 +219,7 @@ export default defineConfig({
}
})
{

}
```

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
"prettify:ci": "prettier --check src",
"prepack": "yarn build",
"release": "semantic-release",
"release:ci": "yarn release --yes",
"release:ci": "yarn release --yes --skip-npm",
"release:test": "yarn release --no-git-tag-version --no-push --skip-npm",
"test": "cd example && yarn test:ct:ci && yarn test:e2e:ci && yarn test:integration:ci",
"test:integration": "vitest run",
Expand Down
55 changes: 44 additions & 11 deletions src/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ declare global {
namespace Cypress {
type MatchImageOptions = {
screenshotConfig?: Partial<Cypress.ScreenshotDefaultsOptions>;
remoteScreenshotServiceUrl?: string;
diffConfig?: Parameters<typeof pixelmatch>[5];
updateImages?: boolean;
/**
Expand Down Expand Up @@ -90,6 +91,12 @@ export const getConfig = (options: Cypress.MatchImageOptions) => {
| Partial<Cypress.ScreenshotDefaultsOptions>
| undefined) ||
{},
remoteScreenshotServiceUrl:
options.remoteScreenshotServiceUrl ||
(Cypress.env("pluginVisualRegressionRemoteScreenshotServiceUrl") as
| string
| undefined) ||
{},
};
};

Expand All @@ -107,6 +114,7 @@ Cypress.Commands.add(
maxDiffThreshold,
diffConfig,
screenshotConfig,
remoteScreenshotServiceUrl,
} = getConfig(options);

return cy
Expand All @@ -124,17 +132,42 @@ Cypress.Commands.add(
)
.then(({ screenshotPath, title: titleFromTask }) => {
title = titleFromTask;
let imgPath: string;
return ($el ? cy.wrap($el) : cy)
.screenshot(screenshotPath, {
...screenshotConfig,
onAfterScreenshot(el, props) {
imgPath = props.path;
screenshotConfig.onAfterScreenshot?.(el, props);
},
log: false,
})
.then(() => imgPath);

if (remoteScreenshotServiceUrl) {
return cy
.document()
.then((doc) => {
return cy
.request({
url: remoteScreenshotServiceUrl,
method: "POST",
encoding: "binary",
body: {
html: ($el?.html() || doc.body.parentElement?.innerHTML),
},
} as Cypress.RequestOptions)
.then((response) => {
return cy.writeFile(
screenshotPath as string,
response.body,
"binary"
);
});
})
.then(() => screenshotPath as string);
} else {
let imgPath: string;
return ($el ? cy.wrap($el) : cy)
.screenshot(screenshotPath, {
...screenshotConfig,
onAfterScreenshot(el, props) {
imgPath = props.path;
screenshotConfig.onAfterScreenshot?.(el, props);
},
log: false,
})
.then(() => imgPath);
}
})
.then((imgPath) =>
cy
Expand Down