How to use onAfterScreenshot method in Cypress

Best JavaScript code snippet using cypress

Run Cypress automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

retries.mochaEvents.spec.js

Source: retries.mochaEvents.spec.js Github

copy
1const helpers = require('../support/helpers')
2
3const { shouldHaveTestResults, getRunState, cleanseRunStateMap } = helpers
4const { runIsolatedCypress, snapshotMochaEvents, getAutCypress } = helpers.createCypress({ config: { retries: 2, isTextTerminal: true, firefoxGcInterval: null } })
5const { sinon } = Cypress
6const match = Cypress.sinon.match
7
8const threeTestsWithRetry = {
9  suites: {
10    'suite 1': {
11      hooks: ['before', 'beforeEach', 'afterEach', 'after'],
12      tests: [
13        'test 1',
14        { name: 'test 2', fail: 2 },
15        'test 3',
16      ],
17    },
18  },
19}
20
21describe('src/cypress/runner retries mochaEvents', { retries: 0 }, () => {
22  // NOTE: for test-retries
23  it('can set retry config', () => {
24    runIsolatedCypress({}, { config: { retries: 1 } })
25    .then(({ autCypress }) => {
26      expect(autCypress.config()).to.has.property('retries', 1)
27    })
28  })
29
30  it('simple retry', () => {
31    runIsolatedCypress({
32      suites: {
33        'suite 1': {
34          tests: [
35            { name: 'test 1',
36              fail: 1,
37            },
38          ],
39        },
40      },
41    }, { config: { retries: 1 } })
42    .then(snapshotMochaEvents)
43  })
44
45  it('test retry with hooks', () => {
46    runIsolatedCypress({
47      suites: {
48        'suite 1': {
49          hooks: ['before', 'beforeEach', 'afterEach', 'after'],
50          tests: [{ name: 'test 1', fail: 1 }],
51        },
52      },
53    }, { config: { retries: 1 } })
54    .then(snapshotMochaEvents)
55  })
56
57  it('test retry with [only]', () => {
58    runIsolatedCypress({
59      suites: {
60        'suite 1': {
61          hooks: ['before', 'beforeEach', 'afterEach', 'after'],
62          tests: [
63            { name: 'test 1' },
64            { name: 'test 2', fail: 1, only: true },
65            { name: 'test 3' },
66          ],
67        },
68      },
69    }, { config: { retries: 1 } })
70    .then(snapshotMochaEvents)
71  })
72
73  it('can retry from [beforeEach]', () => {
74    runIsolatedCypress({
75      suites: {
76        'suite 1': {
77          hooks: [
78            'before',
79            'beforeEach',
80            { type: 'beforeEach', fail: 1 },
81            'beforeEach',
82            'afterEach',
83            'after',
84          ],
85          tests: [{ name: 'test 1' }],
86        },
87      },
88    }, { config: { retries: 1 } })
89    .then(snapshotMochaEvents)
90  })
91
92  it('can retry from [afterEach]', () => {
93    runIsolatedCypress({
94      hooks: [{ type: 'afterEach', fail: 1 }],
95      suites: {
96        'suite 1': {
97          hooks: [
98            'before',
99            'beforeEach',
100            'beforeEach',
101            'afterEach',
102            'after',
103          ],
104          tests: [{ name: 'test 1' }, 'test 2', 'test 3'],
105        },
106        'suite 2': {
107          hooks: [{ type: 'afterEach', fail: 2 }],
108          tests: ['test 1'],
109        },
110        'suite 3': {
111          tests: ['test 1'],
112        },
113      },
114    }, { config: { retries: 2, isTextTerminal: true } })
115
116    .then(snapshotMochaEvents)
117  })
118
119  it('cant retry from [before]', () => {
120    runIsolatedCypress({
121      suites: {
122        'suite 1': {
123          hooks: [
124            { type: 'before', fail: 1 },
125            'beforeEach',
126            'beforeEach',
127            'afterEach',
128            'afterEach',
129            'after',
130          ],
131          tests: [{ name: 'test 1' }],
132        },
133      },
134    }, { config: { retries: 1 } })
135    .then(snapshotMochaEvents)
136  })
137
138  it('cant retry from [after]', () => {
139    runIsolatedCypress({
140      suites: {
141        'suite 1': {
142          hooks: [
143            'before',
144            'beforeEach',
145            'beforeEach',
146            'afterEach',
147            'afterEach',
148            { type: 'after', fail: 1 },
149          ],
150          tests: [{ name: 'test 1' }],
151        },
152      },
153    }, { config: { retries: 1 } })
154    .then(snapshotMochaEvents)
155  })
156
157  it('three tests with retry', () => {
158    runIsolatedCypress(threeTestsWithRetry, {
159      config: {
160        retries: 2,
161      },
162    })
163    .then(snapshotMochaEvents)
164  })
165
166  describe('screenshots', () => {
167    it('retry screenshot in test body', () => {
168      let onAfterScreenshot
169
170      runIsolatedCypress({
171        suites: {
172          'suite 1': {
173            tests: [
174              {
175                name: 'test 1',
176                fn: () => {
177                  cy.screenshot()
178                  cy.then(() => assert(false))
179                },
180                eval: true,
181              },
182            ],
183          },
184        },
185      }, { config: { retries: 1 },
186        onBeforeRun ({ autCypress }) {
187          autCypress.Screenshot.onAfterScreenshot = cy.stub()
188          onAfterScreenshot = cy.stub()
189          autCypress.on('after:screenshot', onAfterScreenshot)
190        },
191      })
192      .then(({ autCypress }) => {
193        expect(autCypress.automation.withArgs('take:screenshot')).callCount(4)
194        expect(autCypress.automation.withArgs('take:screenshot').args).matchDeep([
195          { 1: { testAttemptIndex: 0 } },
196          { 1: { testAttemptIndex: 0 } },
197          { 1: { testAttemptIndex: 1 } },
198          { 1: { testAttemptIndex: 1 } },
199        ])
200
201        expect(autCypress.automation.withArgs('take:screenshot').args[0]).matchSnapshot({ startTime: match.string, testAttemptIndex: match(0) })
202        expect(onAfterScreenshot.args[0][0]).to.matchSnapshot({ testAttemptIndex: match(0) })
203        expect(onAfterScreenshot.args[2][0]).to.matchDeep({ testAttemptIndex: 1 })
204      })
205    })
206
207    it('retry screenshot in hook', () => {
208      let onAfterScreenshot
209
210      runIsolatedCypress({
211        suites: {
212          'suite 1': {
213            hooks: [
214              {
215                type: 'beforeEach',
216                fn: () => {
217                  cy.screenshot()
218                  cy.then(() => assert(false))
219                },
220                eval: true,
221              },
222            ],
223            tests: [
224              {
225                name: 'test 1',
226              },
227            ],
228          },
229        },
230      }, { config: { retries: 1 },
231        onBeforeRun ({ autCypress }) {
232          autCypress.Screenshot.onAfterScreenshot = cy.stub()
233          onAfterScreenshot = cy.stub()
234          autCypress.on('after:screenshot', onAfterScreenshot)
235        },
236      })
237      .then(({ autCypress }) => {
238        expect(autCypress.automation.withArgs('take:screenshot')).callCount(4)
239        expect(autCypress.automation.withArgs('take:screenshot').args).matchDeep([
240          { 1: { testAttemptIndex: 0 } },
241          { 1: { testAttemptIndex: 0 } },
242          { 1: { testAttemptIndex: 1 } },
243          { 1: { testAttemptIndex: 1 } },
244        ])
245
246        expect(onAfterScreenshot.args[0][0]).matchDeep({ testAttemptIndex: 0 })
247        expect(onAfterScreenshot.args[2][0]).matchDeep({ testAttemptIndex: 1 })
248      })
249    })
250  })
251
252  // https://github.com/cypress-io/cypress/issues/8363
253  describe('cleanses errors before emitting', () => {
254    it('does not try to serialize error with err.actual as DOM node', () => {
255      runIsolatedCypress(() => {
256        it('visits', () => {
257          cy.visit('/fixtures/dom.html')
258          cy.get('#button').should('not.be.visible')
259        })
260      }, { config: { defaultCommandTimeout: 200 } })
261      // should not have err.actual, expected properties since the subject is a DOM element
262      .then(snapshotMochaEvents)
263    })
264  })
265
266  describe('save/reload state', () => {
267    const serializeState = () => {
268      return getRunState(getAutCypress())
269    }
270
271    const loadStateFromSnapshot = (cypressConfig, name) => {
272      cy.task('getSnapshot', {
273        file: Cypress.spec.name,
274        exactSpecName: name,
275      })
276      .then((state) => {
277        cypressConfig[1].state = state
278      })
279    }
280
281    // NOTE: for test-retries
282    describe('retries rehydrate spec state after navigation', () => {
283      let realState
284
285      let runCount = 0
286      const failThenSerialize = () => {
287        if (!runCount++) {
288          assert(false, 'stub 3 fail')
289        }
290
291        assert(true, 'stub 3 pass')
292
293        return realState = serializeState()
294      }
295
296      let runCount2 = 0
297      const failOnce = () => {
298        if (!runCount2++) {
299          assert(false, 'stub 2 fail')
300        }
301
302        assert(true, 'stub 2 pass')
303      }
304
305      const stub1 = sinon.stub()
306      const stub2 = sinon.stub().callsFake(failOnce)
307      const stub3 = sinon.stub().callsFake(failThenSerialize)
308
309      let cypressConfig = [
310        {
311          suites: {
312            'suite 1': {
313              hooks: [
314                'before',
315                'beforeEach',
316                'afterEach',
317                'after',
318              ],
319              tests: [{ name: 'test 1', fn: stub1 }],
320            },
321            'suite 2': {
322              tests: [
323                { name: 'test 1', fn: stub2 },
324                { name: 'test 2', fn: stub3 },
325                'test 3',
326              ],
327            },
328          },
329        }, { config: { retries: 1 } },
330      ]
331
332      it('1/2', () => {
333        runIsolatedCypress(...cypressConfig)
334        .then(shouldHaveTestResults(4, 0))
335        .then(() => {
336          expect(realState).to.matchSnapshot(cleanseRunStateMap, 'serialize state - retries')
337        })
338      })
339
340      it('2/2', () => {
341        loadStateFromSnapshot(cypressConfig, 'serialize state - retries')
342        runIsolatedCypress(...cypressConfig)
343        .then(shouldHaveTestResults(4, 0))
344        .then(() => {
345          expect(stub1).to.calledOnce
346          expect(stub2).to.calledTwice
347          expect(stub3).calledThrice
348        })
349      })
350    })
351  })
352})
353
Full Screen

toMatchImageSnapshot.js

Source: toMatchImageSnapshot.js Github

copy
1/* globals cy */
2/* eslint-env browser */
3const { MATCH_IMAGE } = require('../tasks/taskNames');
4const getTaskData = require('../utils/commands/getTaskData');
5const logMessage = require('../utils/commands/logMessage');
6const { NO_LOG } = require('../constants');
7const { COMMAND_MATCH_IMAGE_SNAPSHOT: commandName } = require('./commandNames');
8const getImageData = require('../utils/image/getImageData');
9const {
10  getImageConfig,
11  getScreenshotConfig,
12  getCustomName,
13  getCustomSeparator,
14} = require('../config');
15
16function afterScreenshot(taskData) {
17  return ($el, props) => {
18    // See this url for contents of `props`:
19    // https://docs.cypress.io/api/commands/screenshot.html#Get-screenshot-info-from-the-onAfterScreenshot-callback
20    const win = $el.get(0).ownerDocument.defaultView;
21    taskData.image = getImageData(props, win.devicePixelRatio);
22    taskData.isImage = true;
23    delete taskData.subject;
24  };
25}
26
27async function toMatchImageSnapshot(subject, commandOptions) {
28  const options = getImageConfig(commandOptions);
29  const customName = getCustomName(commandOptions);
30  const customSeparator = getCustomSeparator(commandOptions);
31
32  const taskData = await getTaskData({
33    commandName,
34    options,
35    customName,
36    customSeparator,
37    subject,
38  });
39
40  const screenShotConfig = getScreenshotConfig(commandOptions);
41  const afterScreenshotFn = afterScreenshot(taskData);
42  if (screenShotConfig.onAfterScreenshot) {
43    const afterScreenshotCallback = screenShotConfig.onAfterScreenshot;
44    screenShotConfig.onAfterScreenshot = (...args) => {
45      afterScreenshotFn.apply(this, args);
46      afterScreenshotCallback.apply(this, args);
47    };
48  } else {
49    screenShotConfig.onAfterScreenshot = afterScreenshotFn;
50  }
51
52  return cy
53    .wrap(subject, NO_LOG)
54    .screenshot(taskData.snapshotTitle, screenShotConfig)
55    .then(() => cy.task(MATCH_IMAGE, taskData, NO_LOG).then(logMessage));
56}
57
58module.exports = toMatchImageSnapshot;
59
Full Screen

Accelerate Your Automation Test Cycles With LambdaTest

Leverage LambdaTest’s cloud-based platform to execute your automation tests in parallel and trim down your test execution time significantly. Your first 100 automation testing minutes are on us.

Try LambdaTest

Run JavaScript Tests on LambdaTest Cloud Grid

Execute automation tests with Cypress on a cloud-based Grid of 3000+ real browsers and operating systems for both web and mobile applications.

Test now for Free
LambdaTestX

We use cookies to give you the best experience. Cookies help to provide a more personalized experience and relevant advertising for you, and web analytics for us. Learn More in our Cookies policy, Privacy & Terms of service

Allow Cookie
Sarah

I hope you find the best code examples for your project.

If you want to accelerate automated browser testing, try LambdaTest. Your first 100 automation testing minutes are FREE.

Sarah Elson (Product & Growth Lead)