cypress-image-snapshot
cypress-image-snapshot copied to clipboard
Error: EPERM: operation not permitted, copyfile
I bumped the package from 6.1.1 to 9.0.1 and started getting this error when I re-run the tests. The initial run works fine but it tries to copy the files to the same directory with a .snap suffix for the consequent runs and throws this error below.
It seems to override the files and doesn't have the permission to do so. Though, it shouldn't override them if the snapshots are the same, right?
1) size-small-ltr:
Error: EPERM: operation not permitted, copyfile '/e2e/packages/package/screenshots/src/components/avatar/Avatar.vrt.ts/size-small-ltr.png' -> '/e2e/packages/package/screenshots/src/components/avatar/Avatar.vrt.ts/size-small-ltr.snap.png'
It doesn't have any stack trace, only this error which makes it hard to debug. I run the tests on Docker locally.
A similar error was reported here.
Cypress: v13.6.2 Docker image: cypress/included:13.6.2 Webpack: v5.89.0 OS: macOS Sonoma 14.1.1
Can you give some detail on how you've organised things with config options and folder structures?
I've not seen or been able to recreate this error so far
We have a monorepo that holds web libraries hold Vue and React component libraries, and others such as libraries to run Cypress tests for Vue and React components.
vue-library/
react-library/
env-core/ // holds framework-agnosting Cypress config
env-react/
env-vue/
env-core
This is the base Cypress config that it holds
export default {
// `devServer` is provided by the platform packages
component: {
video: false,
specPattern: "**/*.vrt.{jsx,tsx,ts,js}",
// This folder is different from the snapshot plugins folder because it's recreated from scratch on every test run
screenshotsFolder: ".ui/screenshots/.tmp",
fixturesFolder: ".ui-env/dist/vrt/fixtures",
supportFile: ".ui-env/dist/vrt/support/component.js",
indexHtmlFile: ".ui-env/dist/vrt/support/component-index.html",
setupNodeEvents: (
on: Cypress.PluginEvents,
config: Cypress.PluginConfigOptions
) => {
addMatchImageSnapshotPlugin(on);
cypressSplit(on, config);
return config;
},
},
};
env-vue and env-react
These have framework dependencies and they get the base config from env-core
import { defineConfig } from "cypress";
import cypressConfig from "@monorepo/env-core/dist/vrt/cypress.config.base";
import webpackConfig from "./webpack.config";
export default defineConfig({
component: {
devServer: {
framework: "react",
bundler: "webpack",
webpackConfig,
},
...cypressConfig.component,
},
});
And this is the docker command that I run
docker run -i --rm -v /Users/user/workspace/monorepo:/e2e -v /Users/user/workspace/monorepo/packages/env-core:/e2e/packages/vue-library/.ui-env -w /e2e --ipc=host --shm-size=2g --entrypoint=cypress cypress/included:13.6.2 run --component --project /e2e/packages/vue-library --config-file /e2e/packages/vue-library/.ui-env/dist/vrt/cypress.config.js --spec packages/vue-library/dist/components/action-bar,packages/vue-library/src/components/action-bar
I encountered the same problem, the error is coming from this line:
if (updated) {
log('snapshot updated with new version')
}
await fs.copyFile(snapshotNameFullPath, snapshotDotPath) < ---- error coming from here
// don't remove if the paths are the same, this can happen
// if the user passes empty string for snapFilenameExtension
I think the root cause of this problem is a wrong permission somewhere in the docker container. I'm using gitlab-ci-local to test my pipeline locally, which has a job for visual testing using this plugin.
It works fine if I run it on my machine from terminal, outside of gitlab-ci-local as an npm command, I did not try yet on GitLab itself.
My question is, is there any reason why this code is there? I can see that we are creating a copy of the snapshot, then after processing the current screenshot, we update the original snapshot with the copy we created.
const isExist = await pathExists(snapshotDotPath)
if (isExist) {
await fs.copyFile(snapshotDotPath, snapshotNameFullPath)
}
/* .... processing screenshot .... */
if (updated) {
log('snapshot updated with new version')
}
await fs.copyFile(snapshotNameFullPath, snapshotDotPath) < ---- error coming from here
// don't remove if the paths are the same, this can happen
// if the user passes empty string for snapFilenameExtension
Is something modifying the original snapshot in the process?