miragejs / ember-cli-mirage

An Ember Addon to easily add Mirage JS to your Ember app.
http://ember-cli-mirage.com
MIT License
863 stars 441 forks source link

How to integrate a ember app + mirage with cypress? #1995

Open brunoocasali opened 4 years ago

brunoocasali commented 4 years ago

Question:

I have some e2e tests in cypress and today I've started to setup mirage (most of the routes are complete), but I need some context switching between scenarios inside the test.

I know the tutorial here: https://miragejs.com/quickstarts/cypress but I can't use this because mirage has already started when cypress run (or I just don't know how to do that).

Is there any way to use my already configured (ember-data/ember app + mirage) with cypress?

samselikoff commented 4 years ago

Hm – honestly, I might try moving off of Ember CLI Mirage and just using the miragejs package directly.

Ember CLI Mirage just auto-detects the files and passes them into your server, but you can use plain imports with miragejs to do that. Then you'd have total control over how and when your server is started and stopped. (We are planning on adding APIs to ec-mirage to allow for this kind of lower-level control.)

If you wanted to stay on ec-mirage, you could set ENV['ember-cli-mirage'].enabled = false and then follow the logic in the initializer to start Mirage yourself. I think you'd just need startMirage from here:

https://github.com/miragejs/ember-cli-mirage/blob/master/app/initializers/ember-cli-mirage.js

Think there was an example of it here from way back when: https://github.com/miragejs/ember-cli-mirage/pull/323/files

brunoocasali commented 4 years ago

Thanks to your advices I'm almost done!

The tests already deal with mirage data! :D And now I'm in trouble with development server and other things 😄

PS: (I've removed ember-cli-mirage from app). By the way I've added this:

// app/initializers/cypress.js
import { Server, Response } from "miragejs";
import config from 'dash/config/environment';

export default {
  name: 'cypress.js',

  initialize() {
    if (window.Cypress) {
      new Server({
        environment: "test",

        routes() {
          let methods = ["get", "put", "patch", "post", "delete"];
          let hosts = [config.HOST, config.DOORMAN]; // my app connect with multi api's

          hosts.forEach((host) => {
            this.urlPrefix = host;

            methods.forEach((method) => {
              this[method]("/*", async (schema, request) => {
                let [status, headers, body] = await window.handleFromCypress(request);

                return new Response(status, headers, body);
              })
            })
          });
        }
      })
    }
  }
};
// mirage/config.js
import { Server, Model, belongsTo, JSONAPISerializer } from "miragejs"

import snakeCase from 'lodash.snakecase'; // used in serializers to transform attr keys.

export function makeServer({ environment = "test" } = {}) {
  return new Server({
    environment,

    models: {
      user: Model,
      store: Model,
      sale: Model,
      'store-user': Model.extend({
        company: belongsTo('store'),
        user: belongsTo('user')
      })
    },

    // omitted...
    // serializers
    // routes 
  });
}

And the cypress/mirage handler

// cypress/support/index.js
Cypress.on("window:before:load", (win) => {
  win.handleFromCypress = function (request) {
    return fetch(request.url, {
      method: request.method,
      headers: request.requestHeaders,
      body: request.requestBody,
    }).then((res) => {
      let content =
        res.headers.map["content-type"] === "application/json"
          ? res.json()
          : res.text()
      return new Promise((resolve) => {
        content.then((body) => resolve([res.status, res.headers, body]))
      })
    })
  }
})

But now I've some questions, I'm glad if you can help:

1) Is there a way to get discover emberdata models working with this kind of setup?

2) I've found one of yours stackoverflow questions about importing files from outside of app/ in ember. Now I'm trying to start mirage inside of a new initializer based on ember-cli-mirage addon (as you suggested) that loads makeServer from mirage/config (outside of app) but I just get import errors.

3) (I think this is not related to mirage itself, but if you know something about it will be great ;)) I've noticed my factories/model definitions can't find @ember/string when I running with cypress (they worked when I had the ec-mirage), do you know something about this kind of behaviour? (because of this I needed to install extra lodash libraries to do the @ember/string job!)

@samselikoff thanks a lot for your time, you rocks!