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

Test machine has empty state history after tests finish #1

Open
bahmutov opened this issue Oct 19, 2019 · 4 comments
Open

Test machine has empty state history after tests finish #1

bahmutov opened this issue Oct 19, 2019 · 4 comments

Comments

@bahmutov
Copy link
Owner

bahmutov commented Oct 19, 2019

The Cypress test seems to drive the app using test model correctly. I can see events going according to the path. But when the tests finish, the test model collects state history, which is empty

Screen Shot 2019-10-19 at 9 37 47 AM

Here is the problem: we really have 2 state machines:

  1. the first machine is created by the application and is in its code
// src/toggle.js
// https://github.com/bahmutov/xstate-test-with-cypress-example/blob/37134b193ee8418738b35b0abf534c4ea1cf658c/src/toggle.js
import React from 'react'
import { interpret } from 'xstate'
import { toggleMachine } from './model'

export default class Toggle extends React.Component {
  state = {
    current: toggleMachine.initialState
  }

  service = interpret(toggleMachine).onTransition(current => {
    console.log('app: transition, current is', current)
    this.setState({ current })
  })
...
  1. The second machine is the one the test uses to create its model and then drive along each path.
// cypress/integration/toggle-spec.js
// https://github.com/bahmutov/xstate-test-with-cypress-example/blob/master/cypress/integration/toggle-spec.js
import { createModel } from '@xstate/test'
import { toggleMachine } from '../../src/model'

const toggleModel = createModel(toggleMachine).withEvents({
  TOGGLE: {
    exec: () => {
      console.log('test toggle model TOGGLE')
      debugger
      cy.log('clicking button')
      cy.get('button').click()
    }
  }
})
...

So while we drive along the test machine we don't know what states the application state machine set. I am thinking we could either

  1. replace application's state machine at the start of the test (during cy.visit) with test state machine
  2. or copy state history from application's state machine after each test finishes back to the test state machine so that after all tests finish we know what has been covered
@bahmutov bahmutov changed the title How to copy state history from app machine to test model? Test machine has empty state history after tests finish Oct 19, 2019
@bahmutov
Copy link
Owner Author

I kind of solved this, but I don't know why this works really - and the sequence of commands is wrong in the command log

import { Machine } from 'xstate'

export const toggleMachine = Machine({
  id: 'toggle',
  initial: 'inactive',
  states: {
    inactive: {
      on: {
        TOGGLE: 'active'
      },
      meta: {
        test: () => {
          console.log('model meta test')
          return new Promise(resolve => {
            cy.contains('button', 'Off')
              .should('be.visible')
              .then(() => {
                resolve()
                return null
              })
          })
        }
      }
    },
    active: {
      on: {
        TOGGLE: 'inactive'
      },
      meta: {
        test: () => {
          console.log('model meta test')
          return new Promise(resolve => {
            cy.contains('button', 'On')
              .should('be.visible')
              .then(() => {
                resolve()
                return null
              })
          })
        }
      }
    }
  }
})

Screen Shot 2019-10-19 at 10 03 03 AM

Notice how clicking on the button is in the "After" section - I could not get it to work from path.test() promise for some reason yet.

@davidkpiano
Copy link

The tests (under meta.test) and the actions (under [event].exec) both need to be async, and should not resolve until they have actually finished the async task.

Not sure how to do this manually with Cypress yet; it's different than how it normally works.

@chit786
Copy link

chit786 commented Nov 5, 2019

@bahmutov looking forward to hear more on this. kudos to your efforts!

I also stumbled upon this thread after reading @davidkpiano state machines article and faced same issue with cypress.

@Akshaya2312
Copy link

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants