jaredpalmer / cypress-image-snapshot

Catch visual regressions in Cypress
MIT License
887 stars 160 forks source link

Need actual image as a seperate image #176

Open nani554 opened 3 years ago

nani554 commented 3 years ago
  1. I have a scenario where i have baseline and i have diff image(which shows difference of baseline and actual image), now i need actual image as a seperate image, could you please point me to correct direction.
  2. I need "actual image" as a seperate image, so that i can validate those and replace "baseline images" with the "actual images"
  3. I would like to store that actual image in a seperate folder using "fs".

version details: "cypress": "^4.11.0", "cypress-image-snapshot": "^3.1.1",

Thank You

adhamqodirov commented 3 years ago

This is useful feature. please take a look to this ...

nani554 commented 3 years ago

okay, what i have done is basically is hacky way which goes like this: i'm creating new image(actual image) again aside seperately using cy.screenshot() command,

code:

cy.matchImageSnapshot(imageName);// which basically compare old image with new image//current image
cy.screenshot(imageName); // creates a new image aside

so here two things are happening

you are using this package command to compare and get diff image. you are again creating a new image using cy.screenshot() (cypress default screenshot command). By doing above, two functionalities are being fullfilled:

you can seee diff using "package command" you can have a new image using "cypress screenshot command"

again im using fs to batch commands to place new images in a desired folder and im identifying weather image is the new image or not, for this iam placing new image(while capturing) inside "new_baselines" folder

szaboge commented 2 years ago

Another solution to create a command for that.

Cypress.Commands.add(
  'visualTest',
  {
    prevSubject: 'optional',
  },
  (subject, options) => {
    const fileName = `${Cypress.currentTest.titlePath.join(' -- ')}.snap`;
    if (subject) {
      cy.wrap(subject).screenshot(fileName, options);
      cy.wrap(subject).matchImageSnapshot(options);
    } else {
      cy.screenshot(fileName, options);
      cy.matchImageSnapshot(options);
    }
  },
);

That allows to use it purely cy.visualTest() or chain it to an elment cy.get('element').visualTest()

tkharuk commented 2 years ago

@szaboge when I try to do something like in your example, I have a proper, wrapped Chainer of which I call matchImageSnapshot. But then, inside of matchImageSnapshot, the subject is null. Do you have any ideas what could be wrong?

szaboge commented 2 years ago

The subject is null when you call purely on the cy object like the example above cy.visualTest(), and if you have a previous chainer like cy.get('element'), and you call that on it, in that case your subject will be that (cy.get('element').visualTest()). You can read more here: https://docs.cypress.io/api/cypress-api/custom-commands#Require-Element

tkharuk commented 2 years ago

yeah, I know. Debugged it multiple times, still not sure what's the issue. Actually, subject is not null but undefined.

cy.get(part_of_page).matchImageByOS();

// ...

// my cypress/commands
Cypress.Commands.add(
  'matchImageByOS',
  { prevSubject: ['optional', 'element'] },
  (subject, name, customConfigs) => {
    const target = subject ? cy.wrap(subject) : cy;
    const { isHeadless } = Cypress.browser;

    // ... some custom stuff

    target.matchImageSnapshot(customName, customConfig); // target is a Chainer, not Cy object
  }
);

// package cypress-image-snapshot/command
function matchImageSnapshotCommand(defaultOptions) {
  return function matchImageSnapshot(subject, maybeName, commandOptions) {
  //                                 ^ subject is `undefined`

...
Screenshot 2022-06-23 at 10 54 06 AM Screenshot 2022-06-23 at 10 55 07 AM
szaboge commented 2 years ago

Yeah, looks good. Maybe your subject is not an element? With the second option you filter the usecases. prevSubject: ['optional', 'element']

https://docs.cypress.io/api/cypress-api/custom-commands#Optional-with-Types In the documentation:

  {
    prevSubject: ['optional', 'window', 'document', 'element'],
  },
  (subject, options) => {
    // subject could be undefined
    // since it's optional.
    //
    // if it's present
    // then it's window, document, or element.
    // - when window or document we'll query the entire DOM.
    // - when element we'll query only inside of its children.

Could you make a try without the 'element' argument?

tkharuk commented 2 years ago

Yeah, did try putting just element - same results