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

Record fixtures automatically #1266

Closed
Raathigesh opened this Issue Feb 7, 2018 · 13 comments

Comments

5 participants
@Raathigesh
Copy link

Raathigesh commented Feb 7, 2018

We are trying to record fixtures during the initial run and then use the fixtures for the subsequent runs.

But in-order to implement this feature, we have to get the response from the server and write it to the fixture folder as below.

cy.server({
     onRequest: () => {
     },
     onResponse: response => {
          writeFixture(response.url, response.body);
     }    
});

But since we don't have access to node in the test code, we can not do this because writeFixture is trying to write the fixture to the file system.

We though of using a plugin since plugins runs on node but since plugin API is still being developed, there are no events to listen to XHR requests and responses.

Is there any other way this could be done?

@bahmutov

This comment has been minimized.

Copy link
Collaborator

bahmutov commented Feb 7, 2018

@Raathigesh

This comment has been minimized.

Copy link
Author

Raathigesh commented Feb 7, 2018

I did not. This is helpful. Thanks alot!

Closing this for now. Will re-open if I run into any roadblocks.

@Raathigesh Raathigesh closed this Feb 7, 2018

@Raathigesh

This comment has been minimized.

Copy link
Author

Raathigesh commented Feb 7, 2018

So when I try to write the file with the following code

describe('Login', function () {
    
    it('shold do', () => {
        cy.server({
            onResponse: response => {
                const fullPath = `C:\\SafetyNet\\cypress\\fixtures\\sample.json`;            
                return cy.writeFile(fullPath, {
                });
            }    
        });

        cy.route({
            method: 'GET',      // Route all GET requests
            url: '*'      // and force the response to be: []
          })

        cy.visit('http://localhost:8080/app');
    })
});

Cypress complains as below.

Error:         Uncaught CypressError: Cypress detected that you returned a promise from a command while also invoking one or more cy commands in that promise.

The command that returned the promise was:

  > cy.visit()

The cy command you invoked inside the promise was:

  > cy.writeFile()

Because Cypress commands are already promise-like, you don't need to wrap them or return your own promise.

Cypress will resolve your command with whatever the final Cypress command yields.

The reason this is an error instead of a warning is because Cypress internally queues commands serially whereas Promises execute as soon as they are invoked. Attempting to reconcile this would prevent Cypress from ever resolving.

https://on.cypress.io/returning-promise-and-commands-in-another-command

This error originated from your application code, not from Cypress.

When Cypress detects uncaught errors originating from your application it will automatically fail the current test.

This behavior is configurable, and you can choose to turn this off by listening to the 'uncaught:exception' event.

https://on.cypress.io/uncaught-exception-from-application

@Raathigesh Raathigesh reopened this Feb 7, 2018

@brian-mann

This comment has been minimized.

Copy link
Member

brian-mann commented Feb 7, 2018

What I would do here is just use the Dev tools to accomplish this - it's very easy. You can just use the Network Tab and save the server responses to a file. Done!

@jennifer-shehane

This comment has been minimized.

Copy link
Member

jennifer-shehane commented Feb 7, 2018

We have an example in our docs for this here: https://on.cypress.io/writefile#JSON

cy.request('https://jsonplaceholder.typicode.com/users').then((response) => {
  cy.writeFile('cypress/fixtures/users.json', response.body)
})

// our fixture file is now generated and can be used
cy.fixture('users').then((users) => {
  expect(users[0].name).to.exist
})
@Raathigesh

This comment has been minimized.

Copy link
Author

Raathigesh commented Feb 7, 2018

@brian-mann The idea is to automate the fixture creation. Using dev tool seems like a lot of work. We thought of using chrome puppeteer to record fixtures separately but we wanted to see whether we can accomplish this with just cypress.

@jennifer-shehane Thank you! But the issue with this approach is that we are specifying the URL we want to request. The idea we want to get it to work is, any XHR request to be converted to a fixture and then read those fixtures (hopefully through cy.readFile()) and register them programmatically.
Is there a way to get cy.writeFile() to work inside the onResponse() callback of the server ?

@brian-mann

This comment has been minimized.

Copy link
Member

brian-mann commented Feb 7, 2018

How many fixtures are we talking about here? You could also just do this at your server level - whenever it responds dump the response body to a file. We're only talking about doing this ONCE not each time the test runs right?

You can probably use cy.now('writeFile', args...) here which avoids enqueuing and will kickoff the command and a return a promise immediately. That will avoid the enqueuing checks.

@Raathigesh

This comment has been minimized.

Copy link
Author

Raathigesh commented Feb 8, 2018

The idea of this experiment is to record all xhr calls as fixtures in the initial run (when the developer is witting the test) and then use them in the consecutive runs. The motivation behind this approach is, the app we are trying to test talks to multiple services and getting the test data ready is painful and inconsistent.

I will give cy.now() a try. Thanks you very much.

@bahmutov

This comment has been minimized.

Copy link
Collaborator

bahmutov commented Feb 8, 2018

@Raathigesh

This comment has been minimized.

Copy link
Author

Raathigesh commented Feb 8, 2018

@bahmutov I'll take a look. Looks promising!

@Raathigesh

This comment has been minimized.

Copy link
Author

Raathigesh commented Feb 9, 2018

Now we have automatic fixture recording and replay. But unfortunately lack of support for custom response based on request body for POST requests (#521) is a blocker. I guess we will revisit this once #687 is released.

Thank you for all your support. Closing this for now.

@Raathigesh Raathigesh closed this Feb 9, 2018

@Vaelyr

This comment has been minimized.

Copy link

Vaelyr commented Nov 17, 2018

@Raathigesh any chance you could share your solution?

@Raathigesh

This comment has been minimized.

Copy link
Author

Raathigesh commented Nov 18, 2018

@Vaelyr Unfortunately the solution is not generic enough to open source it. But you could try https://github.com/scottschafer/cypressautomocker which is pretty much the same. Also, I can answer questions you have if that helps!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.