chore: add or improve mount JSDocs (#24475)

* Add or improve JSDoc

* Address code review comments

* Apply suggestions from code review

Co-authored-by: Zachary Williams <ZachJW34@gmail.com>

* Update npm/react/src/mount.ts

Co-authored-by: Zachary Williams <ZachJW34@gmail.com>

* Apply suggestions from code review

Co-authored-by: Stokes Player <stokes@cypress.io>

* on links

Co-authored-by: Zachary Williams <ZachJW34@gmail.com>
Co-authored-by: Stokes Player <stokes@cypress.io>
Co-authored-by: Lachlan Miller <lachlan.miller.1990@outlook.com>
This commit is contained in:
rockindahizzy
2022-11-04 02:26:01 -05:00
committed by GitHub
parent 294985f8b3
commit 7aba05b1a4
9 changed files with 116 additions and 30 deletions

3
.gitignore vendored
View File

@@ -117,6 +117,9 @@ cli/visual-snapshots
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
# Fleet
.fleet/
# User-specific stuff
.idea
.idea/**/workspace.xml

View File

@@ -283,31 +283,33 @@ function setupComponent<T> (
/**
* Mounts an Angular component inside Cypress browser
*
* @param {Type<T> | string} component Angular component being mounted or its template
* @param {MountConfig<T>} config configuration used to configure the TestBed
* @param component Angular component being mounted or its template
* @param config configuration used to configure the TestBed
* @example
* import { HelloWorldComponent } from 'hello-world/hello-world.component'
* import { mount } from '@cypress/angular'
* import { StepperComponent } from './stepper.component'
* import { MyService } from 'services/my.service'
* import { SharedModule } from 'shared/shared.module';
* import { mount } from '@cypress/angular'
* it('can mount', () => {
* mount(HelloWorldComponent, {
* providers: [MyService],
* imports: [SharedModule]
* })
* cy.get('h1').contains('Hello World')
* it('mounts', () => {
* mount(StepperComponent, {
* providers: [MyService],
* imports: [SharedModule]
* })
* cy.get('[data-cy=increment]').click()
* cy.get('[data-cy=counter]').should('have.text', '1')
* })
*
* or
* // or
*
* it('can mount with template', () => {
* mount('<app-hello-world></app-hello-world>', {
* declarations: [HelloWorldComponent],
* providers: [MyService],
* imports: [SharedModule]
* })
* it('mounts with template', () => {
* mount('<app-stepper></app-stepper>', {
* declarations: [StepperComponent],
* })
* })
* @returns Cypress.Chainable<MountResponse<T>>
*
* @see {@link https://on.cypress.io/mounting-angular} for more details.
*
* @returns A component and component fixture
*/
export function mount<T> (
component: Type<T> | string,
@@ -343,6 +345,15 @@ export function mount<T> (
*
* @param {string} alias name you want to use for your cy.spy() alias
* @returns EventEmitter<T>
* @example
* import { StepperComponent } from './stepper.component'
* import { mount, createOutputSpy } from '@cypress/angular'
*
* it('Has spy', () => {
* mount(StepperComponent, { change: createOutputSpy('changeSpy') })
* cy.get('[data-cy=increment]').click()
* cy.get('@changeSpy').should('have.been.called')
* })
*/
export const createOutputSpy = <T>(alias: string) => {
const emitter = new EventEmitter<T>()

View File

@@ -1,5 +1,10 @@
export const ROOT_SELECTOR = '[data-cy-root]'
/**
* Gets the root element used to mount the component.
* @returns {HTMLElement} The root element
* @throws {Error} If the root element is not found
*/
export const getContainerEl = (): HTMLElement => {
const el = document.querySelector<HTMLElement>(ROOT_SELECTOR)
@@ -18,9 +23,12 @@ export function checkForRemovedStyleOptions (mountingOptions: Record<string, any
}
}
/**
* Utility function to register CT side effects and run cleanup code during the "test:before:run" Cypress hook
* @param optionalCallback Callback to be called before the next test runs
*/
export function setupHooks (optionalCallback?: Function) {
// Consumed by the framework "mount" libs. A user might register their own mount in the scaffolded 'commands.js'
// file that is imported by e2e and component support files by default. We don't want CT side effects to run when e2e
// We don't want CT side effects to run when e2e
// testing so we early return.
// System test to verify CT side effects do not pollute e2e: system-tests/test/e2e_with_mount_import_spec.ts
if (Cypress.testingType !== 'component') {

View File

@@ -126,6 +126,8 @@ export const makeMountFn = (
*
* This is designed to be consumed by `npm/react{16,17,18}`, and other React adapters,
* or people writing adapters for third-party, custom adapters.
*
* @param {UnmountArgs} options used during unmounting
*/
export const makeUnmountFn = (options: UnmountArgs) => {
return cy.then(() => {

View File

@@ -25,6 +25,22 @@ const cleanup = () => {
return false
}
/**
* Mounts a React component into the DOM.
* @param jsx {React.ReactNode} The React component to mount.
* @param options {MountOptions} [options={}] options to pass to the mount function.
* @param rerenderKey {string} [rerenderKey] A key to use to force a rerender.
* @see {@link https://on.cypress.io/mounting-react} for more details.
* @example
* import { mount } from '@cypress/react'
* import { Stepper } from './Stepper'
*
* it('mounts', () => {
* mount(<StepperComponent />)
* cy.get('[data-cy=increment]').click()
* cy.get('[data-cy=counter]').should('have.text', '1')
* }
*/
export function mount (jsx: React.ReactNode, options: MountOptions = {}, rerenderKey?: string) {
if (major(React.version) === 18) {
const message = '[cypress/react]: You are using `cypress/react`, which is designed for React <= 17. Consider changing to `cypress/react18`, which is designed for React 18.'
@@ -50,6 +66,11 @@ export function mount (jsx: React.ReactNode, options: MountOptions = {}, rerende
return makeMountFn('mount', jsx, { ReactDom: ReactDOM, ...options }, rerenderKey, internalOptions)
}
/**
* Unmounts the component from the DOM.
* @internal
* @param options - Options for unmounting.
*/
function internalUnmount (options = { log: true }) {
return makeUnmountFn(options)
}

View File

@@ -26,6 +26,26 @@ const cleanup = () => {
return false
}
/**
* Mounts a React component into the DOM.
* @param {import('react').JSX.Element} jsx The React component to mount.
* @param {MountOptions} options Options to pass to the mount function.
* @param {string} rerenderKey A key to use to force a rerender.
*
* @example
* import { mount } from '@cypress/react'
* import { Stepper } from './Stepper'
*
* it('mounts', () => {
* mount(<StepperComponent />)
* cy.get('[data-cy=increment]').click()
* cy.get('[data-cy=counter]').should('have.text', '1')
* }
*
* @see {@link https://on.cypress.io/mounting-react} for more details.
*
* @returns {Cypress.Chainable<MountReturn>} The mounted component.
*/
export function mount (jsx: React.ReactNode, options: MountOptions = {}, rerenderKey?: string) {
// Remove last mounted component if cy.mount is called more than once in a test
// React by default removes the last component when calling render, but we should remove the root

View File

@@ -54,6 +54,8 @@ const getComponentDisplayName = <T extends SvelteComponent>(Component: SvelteCon
* mount(Counter, { props: { count: 42 } })
* cy.get('button').contains(42)
* })
*
* @see {@link https://on.cypress.io/mounting-svelte} for more details.
*/
export function mount<T extends SvelteComponent> (
Component: SvelteConstructor<T>,

View File

@@ -366,7 +366,22 @@ export function mount<
>['vm']
}>
// implementation
/**
* Mounts a component and returns an object containing the component and VueWrapper
* @param componentOptions
* @param options
* @returns {Cypress.Chainable<{wrapper: VueWrapper<T>, component: T}
* @see {@link https://on.cypress.io/mounting-vue} for more details.
* @example
* import { mount } from '@cypress/vue'
* import { Stepper } from './Stepper.vue'
*
* it('mounts', () => {
* cy.mount(Stepper)
* cy.get('[data-cy=increment]').click()
* cy.get('[data-cy=counter]').should('have.text', '1')
* })
*/
export function mount (componentOptions: any, options: any = {}) {
checkForRemovedStyleOptions(options)
// Remove last mounted component if cy.mount is called more than once in a test

View File

@@ -308,16 +308,20 @@ function getComponentDisplayName (componentOptions: any): string {
/**
* Mounts a Vue component inside Cypress browser.
* @param {object} component imported from Vue file
* @param {VueComponent} component imported from Vue file
* @param {MountOptionsArgument} optionsOrProps used to pass options to component being mounted
* @returns {Cypress.Chainable<{wrapper: Wrapper<T>, component: T}
* @example
* import Greeting from './Greeting.vue'
* import { mount } from '@cypress/vue2'
* it('works', () => {
* // pass props, additional extensions, etc
* mount(Greeting, { ... })
* // use any Cypress command to test the component
* cy.get('#greeting').should('be.visible')
* })
* import { mount } from '@cypress/vue'
* import { Stepper } from './Stepper.vue'
*
* it('mounts', () => {
* cy.mount(Stepper)
* cy.get('[data-cy=increment]').click()
* cy.get('[data-cy=counter]').should('have.text', '1')
* })
* @see {@link https://on.cypress.io/mounting-vue} for more details.
*
*/
export const mount = (
component: VueComponent,