Skip to content
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

Cypress visual testing integration #3136

Merged
merged 25 commits into from
May 11, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
505a32a
initial setup
dpatil-magento Apr 15, 2021
7921a88
add test
dpatil-magento Apr 15, 2021
a58d5ec
update
dpatil-magento Apr 16, 2021
4e48d03
Added logic to capture multiple snapshots of full page.
revanth0212 Apr 20, 2021
c2fbdd5
Created command to generate full page screenshot.
revanth0212 Apr 21, 2021
d0abbc0
Updated full page screenshot logic.
revanth0212 Apr 21, 2021
2e0605d
Deleting old screenshots.
revanth0212 Apr 21, 2021
d798307
Updated snapshot.
revanth0212 Apr 21, 2021
70cebe5
Added update snapshot script.
revanth0212 Apr 21, 2021
55b025b
Merge branch 'develop' into dev/ui-test-poc3
revanth0212 Apr 22, 2021
2554671
Deleting unnecessary screenshots.
revanth0212 Apr 22, 2021
cf746e4
Updated snapshot.
revanth0212 Apr 22, 2021
4a709e4
Merge branch 'develop' of github.com:magento/pwa-studio into dev/ui-t…
anthoula Apr 28, 2021
1ccc372
Updated threshold.
revanth0212 Apr 29, 2021
e5daafd
Updated script to load full page before screenshot check.
revanth0212 May 5, 2021
79f6d1b
Using diff method for snapshot comparitions.
revanth0212 May 5, 2021
d016293
Merge branch 'develop' into dev/ui-test-poc3
dpatil-magento May 5, 2021
b1fd270
Using smaller viewport.
revanth0212 May 6, 2021
9f69c7a
Updated snapshot testing for DPI irrespective testing.
revanth0212 May 7, 2021
75b2576
Jest setup.
revanth0212 May 10, 2021
c132415
Added filter modal test.
revanth0212 May 10, 2021
f20e2a3
Added command tests.
revanth0212 May 10, 2021
6fb91aa
Added resize plugin tests.
revanth0212 May 10, 2021
562b159
Setting pixelRatio to 1 after resizing.
revanth0212 May 10, 2021
e3a8e6c
Merge branch 'develop' into dev/ui-test-poc3
dpatil-magento May 11, 2021
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
9 changes: 7 additions & 2 deletions venia-integration-tests/cypress.config.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
{
"baseUrl": "https://develop.pwa-venia.com/",
"defaultCommandTimeout": 10000,
"env": {},
"supportFile": "src/support/index.js",
"pluginsFile": "src/plugins/index.js",
"fixturesFolder": "src/fixtures",
"integrationFolder": "src/tests",
"screenshotsFolder": "src/snapshots",
"pageLoadTimeout": 30000,
"requestTimeout": 30000,
"testFiles": "**/*.spec.js",
"viewportHeight": 900,
"viewportWidth": 1440
"viewportWidth": 1440,
"scrollBehavior": false,
"ignoreTestFiles": ["**/__snapshots__/*", "**/__image_snapshots__/*"],
"env": {}
}
1 change: 1 addition & 0 deletions venia-integration-tests/cypress.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
3 changes: 3 additions & 0 deletions venia-integration-tests/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports = {
testMatch: ['**/__tests__/**/*.[jt]s?(x)']
};
11 changes: 8 additions & 3 deletions venia-integration-tests/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,18 @@
"author": "Magento Commerce",
"license": "MIT",
"devDependencies": {
"cypress": "~6.8.0"
"cypress": "~7.1.0",
"cypress-image-snapshot": "~4.0.1",
"jest": "~26.0.1",
"jimp": "~0.16.1"
},
"scripts": {
"test": "cypress open --browser chrome --config-file cypress.config.json",
"test:firefox": "cypress open --browser firefox --config-file cypress.config.json",
"test:headless": "cypress open --browser chrome --headless --config-file cypress.config.json",
"test:headless": "cypress run --browser chrome --headless --config-file cypress.config.json",
"test:run": "cypress run --browser chrome --config-file cypress.config.json",
"test:debug": "node --inspect-brk ./node_modules/cypress/bin/cypress open --browser chrome --config-file cypress.config.json"
"test:devTest": "jest",
"test:debug": "node --inspect-brk ./node_modules/cypress/bin/cypress run --browser chrome --config-file cypress.config.json",
"test:update-snapshots": "cypress run --browser chrome --config-file cypress.config.json --env updateSnapshots=true"
}
}
1 change: 1 addition & 0 deletions venia-integration-tests/src/fields/categoryPage/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const filterButton = 'button[class^="category-filterButton"]';

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
const { read } = require('jimp');
const { existsSync } = require('fs');
const { matchImageSnapshotPlugin } = require('cypress-image-snapshot/plugin');

const {
addSnapshotResizePlugin,
resizeSnapshot
} = require('../resizeSnapshotPlugin');

jest.mock('jimp', () => ({
read: jest.fn()
}));

jest.mock('cypress-image-snapshot/plugin', () => ({
matchImageSnapshotPlugin: jest.fn()
}));

jest.mock('fs', () => ({
existsSync: jest.fn().mockReturnValue(true),
readFileSync: jest.fn().mockReturnValue('image data')
}));

const mockWriteAsync = jest.fn().mockResolvedValue({});
const mockResize = jest.fn().mockReturnValue({ writeAsync: mockWriteAsync });

beforeAll(() => {
read.mockResolvedValue({
resize: mockResize
});
});

beforeEach(() => {
jest.clearAllMocks();
});

const imageConfig = {
path: 'path/to/the/snapshot/image',
pixelRatio: 2,
dimensions: {
width: 100,
height: 100
}
};

describe('testing resizeSnapshot', () => {
test('should write resized image to filesystem if exists', async () => {
const updatedImageConfig = await resizeSnapshot(imageConfig);

expect(read).toHaveBeenCalledWith('image data');
expect(mockResize).toHaveBeenCalledWith(50, 50);
expect(mockWriteAsync).toHaveBeenCalledWith(
'path/to/the/snapshot/image'
);
expect(updatedImageConfig).toMatchInlineSnapshot(`
Object {
"dimensions": Object {
"height": 50,
"width": 50,
},
"path": "path/to/the/snapshot/image",
"pixelRatio": 1,
}
`);
});

test('should not attemp to resize if image is not available', async () => {
existsSync.mockReturnValueOnce(false).mockReturnValueOnce(false);

const updatedImageConfig = await resizeSnapshot(imageConfig);

expect(mockResize).not.toHaveBeenCalled();
expect(mockWriteAsync).not.toHaveBeenCalled();
expect(updatedImageConfig).toMatchInlineSnapshot(`
Object {
"dimensions": Object {
"height": 100,
"width": 100,
},
"path": "path/to/the/snapshot/image",
"pixelRatio": 2,
}
`);
});
});

describe('testing addSnapshotResizePlugin', () => {
test('should register task and screenshot plugins', () => {
const on = jest.fn();

addSnapshotResizePlugin(on);

expect(on.mock.calls).toMatchInlineSnapshot(`
Array [
Array [
"task",
Object {
"resizeSnapshot": [Function],
},
],
Array [
"after:screenshot",
[Function],
],
]
`);
});

test('after:screenshot should return correct shape', async () => {
const on = jest.fn();

addSnapshotResizePlugin(on);

const [, screenshotResizeFn] = on.mock.calls.find(
call => call[0] === 'after:screenshot'
);

await screenshotResizeFn({ ...imageConfig, name: 'sample snapshot' });

expect(matchImageSnapshotPlugin.mock.calls).toMatchInlineSnapshot(`
Array [
Array [
Object {
"dimensions": Object {
"height": 100,
"width": 100,
},
"name": "sample-snapshot",
"path": "path/to/the/snapshot/image",
"pixelRatio": 2,
},
],
]
`);
});
});
9 changes: 9 additions & 0 deletions venia-integration-tests/src/plugins/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
const {
addMatchImageSnapshotPlugin
} = require('cypress-image-snapshot/plugin');
const { addSnapshotResizePlugin } = require('./resizeSnapshotPlugin');

module.exports = (on, config) => {
addMatchImageSnapshotPlugin(on, config);
addSnapshotResizePlugin(on, config);
};
66 changes: 66 additions & 0 deletions venia-integration-tests/src/plugins/resizeSnapshotPlugin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
const jimp = require('jimp');
const fs = require('fs');
const { matchImageSnapshotPlugin } = require('cypress-image-snapshot/plugin');

const resizeSnapshot = imageConfig => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this the function that resolves differences in terms of resolution and pixel density?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that's the one.

const { path, pixelRatio, dimensions } = imageConfig;
const { width, height } = dimensions;

const newDimensions = {
width: width / pixelRatio,
height: height / pixelRatio
};

if (fs.existsSync(path)) {
const imageData = fs.readFileSync(path);

return jimp
.read(imageData)
.then(image => {
return image
.resize(newDimensions.width, newDimensions.height)
.writeAsync(path)
.then(() => {
return {
...imageConfig,
dimensions: newDimensions,
pixelRatio: 1
};
});
})
.catch(() => {
return;
});
} else {
return Promise.resolve(imageConfig);
}
};

const replaceSpace = str => str.split(' ').join('-');

const adjustDetails = screenshotDetails => {
return {
...screenshotDetails,
name: replaceSpace(screenshotDetails.name),
path: replaceSpace(screenshotDetails.path)
};
};

const addSnapshotResizePlugin = on => {
on('task', {
resizeSnapshot
});
on('after:screenshot', rawScreenshotDetails => {
const screenshotDetails = adjustDetails(rawScreenshotDetails);

return resizeSnapshot(screenshotDetails)
.then(screenshotDetails => {
matchImageSnapshotPlugin(screenshotDetails);
})
.catch(err => {
console.error('Something went wrong', err);
});
});
};

module.exports = { resizeSnapshot, addSnapshotResizePlugin };
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
const mockAdd = jest.fn();
const mockMatchImageSnapshot = jest.fn();
const mockDocument = jest.fn().mockReturnValue({
matchImageSnapshot: mockMatchImageSnapshot
});
const mockInvoke = jest.fn();
const mockGet = jest.fn().mockReturnValue({
invoke: mockInvoke
});

beforeAll(() => {
global.Cypress = {
Commands: {
add: mockAdd
}
};

global.cy = {
document: mockDocument,
get: mockGet
};
});

afterAll(() => {
delete global.Cypress;
delete global.cy;
});

test('should match document snapshot', () => {
require('../fullPageScreenshotCommand');

expect(mockAdd.mock.calls).toMatchInlineSnapshot(`
Array [
Array [
"captureFullPageScreenshot",
[Function],
],
]
`);

const captureFullPageScreenshot = mockAdd.mock.calls[0][1];
captureFullPageScreenshot({ name: 'sample page snapshot' });

expect(mockMatchImageSnapshot.mock.calls).toMatchInlineSnapshot(`
Array [
Array [
"sample-page-snapshot",
Object {
"comparisonMethod": "ssim",
"failureThreshold": 0.01,
"failureThresholdType": "percent",
"name": "sample-page-snapshot",
},
],
]
`);
});

test('should throw error if name is not provided', () => {
require('../fullPageScreenshotCommand');

const captureFullPageScreenshot = mockAdd.mock.calls[0][1];
expect(() => captureFullPageScreenshot({})).toThrow();
});

test('should use custom options if provided', () => {
mockMatchImageSnapshot.mockClear();

require('../fullPageScreenshotCommand');

const captureFullPageScreenshot = mockAdd.mock.calls[0][1];
captureFullPageScreenshot({
name: 'sample page snapshot',
failureThreshold: 0.2
});

expect(mockMatchImageSnapshot.mock.calls).toMatchInlineSnapshot(`
Array [
Array [
"sample-page-snapshot",
Object {
"comparisonMethod": "ssim",
"failureThreshold": 0.2,
"failureThresholdType": "percent",
"name": "sample-page-snapshot",
},
],
]
`);
});
Loading