Use cache to store snapshots

This commit is contained in:
Sidharth Vinod
2024-01-19 12:06:53 +05:30
parent 8754b9dd5d
commit d2c82c1802
7 changed files with 77 additions and 12 deletions

View File

@@ -9,8 +9,44 @@ permissions:
contents: read contents: read
jobs: jobs:
cache:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v2
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 18.x
- name: Cache snapshots
id: cache-snapshot
uses: actions/cache@v4
with:
save-always: true
path: ./cypress/snapshots
key: ${{ runner.os }}-snapshots
- name: Switch to base branch
if: ${{ steps.cache-snapshot.outputs.cache-hit != 'true' }}
uses: actions/checkout@v4
with:
ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.base.sha || github.event_name == 'merge_group' && github.event.merge_group.base.sha || 'develop' }}
- name: Cypress run
uses: cypress-io/github-action@v4
id: cypress-snapshot-gen
if: ${{ steps.cache-snapshot.outputs.cache-hit != 'true' }}
with:
start: pnpm run dev
wait-on: 'http://localhost:9000'
browser: chrome
spec: |
cypress/integration/rendering/flowchart-v2.spec.js
e2e: e2e:
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: cache
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
@@ -27,6 +63,13 @@ jobs:
with: with:
node-version: ${{ matrix.node-version }} node-version: ${{ matrix.node-version }}
- name: Cache snapshots
id: cache-snapshot
uses: actions/cache/restore@v3
with:
path: ./cypress/snapshots
key: ${{ runner.os }}-snapshots
# Install NPM dependencies, cache them correctly # Install NPM dependencies, cache them correctly
# and run all Cypress tests # and run all Cypress tests
- name: Cypress run - name: Cypress run
@@ -38,14 +81,19 @@ jobs:
with: with:
start: pnpm run dev:coverage start: pnpm run dev:coverage
wait-on: 'http://localhost:9000' wait-on: 'http://localhost:9000'
browser: chrome
# Disable recording if we don't have an API key # Disable recording if we don't have an API key
# e.g. if this action was run from a fork # e.g. if this action was run from a fork
record: ${{ secrets.CYPRESS_RECORD_KEY != '' }} record: ${{ secrets.CYPRESS_RECORD_KEY != '' }}
parallel: ${{ secrets.CYPRESS_RECORD_KEY != '' }} parallel: ${{ secrets.CYPRESS_RECORD_KEY != '' }}
# TODO: Remove
spec: |
cypress/integration/rendering/flowchart-v2.spec.js
env: env:
CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }} CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }}
VITEST_COVERAGE: true VITEST_COVERAGE: true
CYPRESS_COMMIT: ${{ github.sha }} CYPRESS_COMMIT: ${{ github.sha }}
- name: Upload Coverage to Codecov - name: Upload Coverage to Codecov
uses: codecov/codecov-action@v3 uses: codecov/codecov-action@v3
# Run step only pushes to develop and pull_requests # Run step only pushes to develop and pull_requests
@@ -57,6 +105,7 @@ jobs:
fail_ci_if_error: false fail_ci_if_error: false
verbose: true verbose: true
token: 6845cc80-77ee-4e17-85a1-026cd95e0766 token: 6845cc80-77ee-4e17-85a1-026cd95e0766
- name: Upload Artifacts - name: Upload Artifacts
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v3
if: ${{ failure() && steps.cypress.conclusion == 'failure' }} if: ${{ failure() && steps.cypress.conclusion == 'failure' }}

View File

@@ -124,6 +124,7 @@
"sidharth", "sidharth",
"sidharthv", "sidharthv",
"sphinxcontrib", "sphinxcontrib",
"ssim",
"startx", "startx",
"starty", "starty",
"statediagram", "statediagram",

View File

@@ -4,12 +4,21 @@ const { defineConfig } = require('cypress');
const { addMatchImageSnapshotPlugin } = require('cypress-image-snapshot/plugin'); const { addMatchImageSnapshotPlugin } = require('cypress-image-snapshot/plugin');
const coverage = require('@cypress/code-coverage/task'); const coverage = require('@cypress/code-coverage/task');
module.exports = defineConfig({ module.exports = defineConfig({
projectId: 'n2sma2', projectId: 'n2sma2',
viewportWidth: 1440,
viewportHeight: 1024,
e2e: { e2e: {
specPattern: 'cypress/integration/**/*.{js,jsx,ts,tsx}', specPattern: 'cypress/integration/**/*.{js,ts}',
setupNodeEvents(on, config) { setupNodeEvents(on, config) {
coverage(on, config); coverage(on, config);
on('before:browser:launch', (browser = {}, launchOptions) => {
if (browser.name === 'chrome' && browser.isHeadless) {
launchOptions.args.push('--window-size=1440,1024', '--force-device-scale-factor=1');
}
return launchOptions;
});
addMatchImageSnapshotPlugin(on, config); addMatchImageSnapshotPlugin(on, config);
// copy any needed variables from process.env to config.env // copy any needed variables from process.env to config.env
config.env.useAppli = process.env.USE_APPLI ? true : false; config.env.useAppli = process.env.USE_APPLI ? true : false;

View File

@@ -117,7 +117,6 @@ describe('Configuration', () => {
}); });
it('should not taint the initial configuration when using multiple directives', () => { it('should not taint the initial configuration when using multiple directives', () => {
const url = 'http://localhost:9000/regression/issue-1874.html'; const url = 'http://localhost:9000/regression/issue-1874.html';
cy.viewport(1440, 1024);
cy.visit(url); cy.visit(url);
cy.get('svg'); cy.get('svg');

View File

@@ -1,14 +1,12 @@
describe('Rerendering', () => { describe('Rerendering', () => {
it('should be able to render after an error has occurred', () => { it('should be able to render after an error has occurred', () => {
const url = 'http://localhost:9000/render-after-error.html'; const url = 'http://localhost:9000/render-after-error.html';
cy.viewport(1440, 1024);
cy.visit(url); cy.visit(url);
cy.get('#graphDiv').should('exist'); cy.get('#graphDiv').should('exist');
}); });
it('should be able to render and rerender a graph via API', () => { it('should be able to render and rerender a graph via API', () => {
const url = 'http://localhost:9000/rerender.html'; const url = 'http://localhost:9000/rerender.html';
cy.viewport(1440, 1024);
cy.visit(url); cy.visit(url);
cy.get('#graph [id^=flowchart-A]').should('have.text', 'XMas'); cy.get('#graph [id^=flowchart-A]').should('have.text', 'XMas');

View File

@@ -245,7 +245,10 @@ describe('Gantt diagram', () => {
const style = svg.attr('style'); const style = svg.attr('style');
expect(style).to.match(/^max-width: [\d.]+px;$/); expect(style).to.match(/^max-width: [\d.]+px;$/);
const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join('')); const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join(''));
expect(maxWidthValue).to.be.within(984 * 0.95, 984 * 1.05); expect(maxWidthValue).to.be.within(
Cypress.config().viewportWidth * 0.95,
Cypress.config().viewportWidth * 1.05
);
}); });
}); });
@@ -285,11 +288,11 @@ describe('Gantt diagram', () => {
{ gantt: { useMaxWidth: false } } { gantt: { useMaxWidth: false } }
); );
cy.get('svg').should((svg) => { cy.get('svg').should((svg) => {
// const height = parseFloat(svg.attr('height'));
const width = parseFloat(svg.attr('width')); const width = parseFloat(svg.attr('width'));
// use within because the absolute value can be slightly different depending on the environment ±5% expect(width).to.be.within(
// expect(height).to.be.within(484 * 0.95, 484 * 1.05); Cypress.config().viewportWidth * 0.95,
expect(width).to.be.within(984 * 0.95, 984 * 1.05); Cypress.config().viewportWidth * 1.05
);
expect(svg).to.not.have.attr('style'); expect(svg).to.not.have.attr('style');
}); });
}); });

View File

@@ -24,8 +24,14 @@
// -- This is will overwrite an existing command -- // -- This is will overwrite an existing command --
// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... }) // Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... })
// import '@percy/cypress';
import { addMatchImageSnapshotCommand } from 'cypress-image-snapshot/command'; import { addMatchImageSnapshotCommand } from 'cypress-image-snapshot/command';
addMatchImageSnapshotCommand(); addMatchImageSnapshotCommand({
comparisonMethod: 'ssim',
failureThreshold: 0.01,
failureThresholdType: 'percent',
customDiffConfig: {
ssim: 'fast',
},
blur: 1,
});