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

cy.visit() Typescript promise chain error - Type 'Chainable<HTMLInputElement>' is missing the following properties #6206

Closed
Dan503 opened this issue Jan 21, 2020 · 5 comments
Labels
type: duplicate This issue or pull request already exists

Comments

@Dan503
Copy link

Dan503 commented Jan 21, 2020

Current behavior:

The following Typescript code produces an error:

const loadInput = (): Promise<HTMLInputElement> => cy.visit('./core/selectors/selectors-test-file.html')
	.then((contentWindow: Window) => {
		let { document } = contentWindow
		const $input = <HTMLInputElement>document.getElementById('textInputID')
		return $input
	})

it("Shouldn't break", async ()=> {
	const $input = await loadInput()
	expect($input.value).to.equal('')
})

The error message I get:

TS2739: Type 'Chainable<HTMLInputElement>' is missing the following properties from type 'Promise<HTMLInputElement>': catch, [Symbol.toStringTag]��

Desired behavior:

The loadInput() function should return a promise that later returns the HTML input DOM element.

Versions

  • Cypress: 3.8.0
  • Node: 12.13.0
  • Browser: Chrome 79.0.3945.130
  • OS: Windows 10

Work around

I worked around the issue by doing this:

const loadInput = (): Promise<HTMLInputElement> => new Promise((resolve) => {
	cy.visit('./core/selectors/selectors-test-file.html')
		.then((contentWindow: Window) => {
			let { document } = contentWindow
			const $input = <HTMLInputElement>document.getElementById('textInputID')
			resolve($input)
		})
})

But now Cypress is complaining about nesting cy.visit() inside a promise. It's just a warning though so I can ignore it.

@jennifer-shehane jennifer-shehane added type: typings Issue related to Cypress types (for TypeScript) and removed topic: typescript labels Mar 3, 2020
@cypress-bot cypress-bot bot added the stage: proposal 💡 No work has been done of this issue label Mar 3, 2020
@karol-majewski
Copy link

I'm not aware of any additional constraints you have, but just in case: isn't that what you're looking for?

cy.visit('./core/selectors/selectors-test-file.html')
  .then(window$ => window$.document.getElementById('textInputID') as HTMLInputElement)
  .should('have.property', 'value', '');

Or, since DOM elements with ids are global variables:

cy
  .visit('./core/selectors/selectors-test-file.html')
  .its('document.textInputID')
  .should('have.property', 'value', '');

Alternatively, if you need to access input from another place:

let input: HTMLInputElement;

cy.visit('./core/selectors/selectors-test-file.html').then(window$ => {
  input = window$.document.getElementById('textInputID') as HTMLInputElement;
});

(Cypress thenables are not Promises, so your original code cannot work.)

@Dan503
Copy link
Author

Dan503 commented Apr 1, 2020

I use the loadInput function a lot and in different scenarios to reduce code repetition.

Based on your comment above though, it sounds like this pattern will work:

const loadInput = (callback) => {
  cy.visit('./core/selectors/selectors-test-file.html').then(window$ => {
    input = window$.document.getElementById('textInputID') as HTMLInputElement;
    callback(input)
  });
}

it("Should work", ()=> {
  loadInput($input => {
    expect($input.value).to.equal('')
  })
})

@Dan503 Dan503 closed this as completed Apr 1, 2020
@Dan503 Dan503 reopened this Apr 1, 2020
@Dan503
Copy link
Author

Dan503 commented Apr 1, 2020

I like the promise async/await syntax a lot more though.

I switched to using cypress-promise to make my code cleaner. Based on the number of downloads, many other developers feel the same way.

It has the annoying issue of triggering the warning though.

NicholasBoll/cypress-promise#6

Is there a way that the warning can be suppressed if we choose that we would prefer to work with promises?

@FFdhorkin
Copy link

FFdhorkin commented May 12, 2020

I like the promise async/await syntax a lot more though.

I switched to using cypress-promise to make my code cleaner. Based on the number of downloads, many other developers feel the same way.

It has the annoying issue of triggering the warning though.

NicholasBoll/cypress-promise#6

Is there a way that the warning can be suppressed if we choose that we would prefer to work with promises?

Just to chime in here... We're using Cypress to validate our API - no UI involved, except for Cypress itself (to inspect requests). Our code often times has >= 5 levels of indentation because we have to keep doing nested then blocks to pull out variables we want to use. And a lot of our helper methods are really messy - I'd like to have a getCount() method that just returns an integer rather than Chainable.

cypress-promise would enable that, and make our code MUCH more readable. But it would also create dozens of warnings in our console, and that's a non-starter. It would be nice to be have some way to suppress that warning. I'm tempted to make a fork of Cypress just to remove that warning... but that seems like a pretty extreme measure.

@sainthkh
Copy link
Contributor

It's a duplicate of #1417.

@jennifer-shehane jennifer-shehane added type: duplicate This issue or pull request already exists and removed stage: proposal 💡 No work has been done of this issue type: typings Issue related to Cypress types (for TypeScript) labels Jul 23, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: duplicate This issue or pull request already exists
Projects
None yet
Development

No branches or pull requests

5 participants