Skip to content

Commit

Permalink
fix: update alias and jsdoc, closes cypress-io/cypress-react-unit-tes…
Browse files Browse the repository at this point in the history
  • Loading branch information
bahmutov committed Jun 12, 2020
1 parent 741a2f6 commit 4bb7caf
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 17 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ Look at the examples in [cypress/component](cypress/component) folder. Here is t
<!-- prettier-ignore-start -->
Spec | Description
--- | ---
[alias](cypress/component/basic/alias) | Retrieve mounted component by its name or alias
[alert-spec.js](cypress/component/basic/alert-spec.js) | Component tries to use `window.alert`
[counter-set-state](cypress/component/basic/counter-set-state) | Counter component that uses `this.state`
[counter-use-hooks](cypress/component/basic/counter-use-hooks) | Counter component that uses `useState` hook
Expand Down
5 changes: 5 additions & 0 deletions cypress/component/basic/alias/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# alias

You can retrieve the created component using default constructor function name or an alias. See [alias-spec.js](alias-spec.js) for examples.

![Alias tests](images/alias.png)
28 changes: 28 additions & 0 deletions cypress/component/basic/alias/alias-spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/// <reference types="cypress" />
import React from 'react'
import { mount } from 'cypress-react-unit-test'

describe('Alias', () => {
it('returns component by its name', () => {
const Greeting = () => <div>Hello!</div>
mount(<Greeting />)
// get the component instance by name "Greeting"
cy.get('@Greeting')
.its('props')
.should('be.empty')
// the component was constructed from the function Greeting
cy.get('@Greeting')
.its('type')
.should('equal', Greeting)
})

it('returns component by given display name', () => {
const GreetingCard = props => <div>Hello {props.name}!</div>
mount(<GreetingCard name="World" />, { alias: 'Hello' })
cy.get('@Hello')
.its('props')
.should('deep.equal', {
name: 'World',
})
})
})
Binary file added cypress/component/basic/alias/images/alias.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
44 changes: 27 additions & 17 deletions lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,34 +29,40 @@ const injectStyles = (options: MountOptions) => () => {
/**
* Mount a React component in a blank document; register it as an alias
* To access: use an alias or original component reference
* @function cy.mount
* @param {React.ReactElement} jsx - component to mount
* @param {string} [Component] - alias to use later
* @example
* @function mount
* @param {React.ReactElement} jsx - component to mount
* @param {MountOptions} [options] - options, like alias, styles
* @see https://github.com/bahmutov/cypress-react-unit-test
* @see https://glebbahmutov.com/blog/my-vision-for-component-tests/
* @example
```
import Hello from './hello.jsx'
// mount and access by alias
cy.mount(<Hello />, 'Hello')
// using default alias
cy.get('@Component')
// using original component
cy.get(Hello)
import Hello from './hello.jsx'
import {mount} from 'cypress-react-unit-test'
it('works', () => {
mount(<Hello onClick={cy.stub()} />)
// use Cypress commands
cy.contains('Hello').click()
})
```
**/
export const mount = (jsx: React.ReactElement, options: MountOptions = {}) => {
checkMountModeEnabled()

// Get the display name property via the component constructor
// @ts-ignore FIXME
const displayName = getDisplayName(jsx.type, options.alias)
const componentName = getDisplayName(jsx.type, options.alias)
const displayName = options.alias || componentName
const message = options.alias
? `<${componentName} ... /> as "${options.alias}"`
: `<${componentName} ... />`
let logInstance: Cypress.Log

return cy
.then(() => {
if (options.log !== false) {
logInstance = Cypress.log({
name: 'mount',
message: [`<${displayName} ... />`],
message: [message],
})
}
})
Expand Down Expand Up @@ -85,7 +91,11 @@ export const mount = (jsx: React.ReactElement, options: MountOptions = {}) => {
}

const reactComponent = React.createElement(React.Fragment, props, jsx)
const CypressTestComponent = reactDomToUse.render(reactComponent, el)
// since we always surround the component with a fragment
// let's get back the original component
// @ts-ignore
const userComponent = reactComponent.props.children
reactDomToUse.render(reactComponent, el)

if (logInstance) {
const logConsoleProps = {
Expand All @@ -109,8 +119,8 @@ export const mount = (jsx: React.ReactElement, options: MountOptions = {}) => {

return (
cy
.wrap(CypressTestComponent, { log: false })
.as(options.alias || displayName)
.wrap(userComponent, { log: false })
.as(displayName)
// by waiting, we give the component's hook a chance to run
// https://github.com/bahmutov/cypress-react-unit-test/issues/200
.wait(1, { log: false })
Expand All @@ -129,7 +139,7 @@ export const mount = (jsx: React.ReactElement, options: MountOptions = {}) => {
}

/**
* Removes any mounted component
* Removes the mounted component
* @see https://github.com/bahmutov/cypress-react-unit-test/tree/master/cypress/component/basic/unmount
* @example
```
Expand Down

0 comments on commit 4bb7caf

Please sign in to comment.