-
Notifications
You must be signed in to change notification settings - Fork 3.3k
fix: Add more precise types to Cypress.Commands #19003
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
fix: Add more precise types to Cypress.Commands #19003
Conversation
Thanks for taking the time to open a PR!
|
953fc80
to
863e725
Compare
863e725
to
cd5d2a9
Compare
@xumepadismal FYI - #18967 issued by @remcohaszing has similar types changes to Cypress.Commands as well. It looks like it takes prevSubject into account. Where you aware? @remcohaszing Did you by chance come across this PR? I'm curious what you both think of each other's proposed changes. Edit- it actually looks like this draft PR was also opened to tackle similar issues: #18880. |
@emilyrohrbough oh I missed these PRs indeed... Here's my thoughts about the difference. Regarding the preSubjectPR #18880 seems to propose more future-proof approach to But on the other hand it doesn't support array of prevSubjects which IS supportred by this PR. You can refer to Regarding the voidIn #18967 return type of ChainableMethods vs ConditionalKeysI'm uncertain about what approach is better but it seems that |
I think this PR does everything #18967 does plus more (
I used |
Hmm I played around this and it seems that TS checks the return type correctly, no? You can return either correct type or nothing. Error if you try to return something inconsistent to interface. |
…dOptions if added in future bonus: fix {prevSubject: 'document'} so that it refer to Document instead of JQuery
Now this PR should also cover everything in #18880. Hopefully I didn't miss anything, review will be welcome :) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cli/types/cypress.d.ts
Outdated
name: T, options: CommandOptions & { prevSubject: S | Array<Exclude<S, 'optional'>> }, fn: CommandFnWithSubject<T, PrevSubjectMap[S]>, | ||
): void | ||
add<T extends keyof Chainable, S extends PrevSubject>( | ||
name: T, options: CommandOptions & { prevSubject: 'optional' | ['optional', ...S[]] }, fn: CommandFnWithSubject<T, void | PrevSubjectMap[S]>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will this section work fine even if 'optional' isn't in the first place?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just pushed a commit to support this case. I'm little bit surprised the code looks even cleaner with this fix :)
I'm not sure if this is the right place to post this, but I got a chance to checkout the changes in the PR, and when overwriting commands like Cypress.Commands.overwrite<'select', 'element'>('select', (originalFn, prevSubject, valueOrTextOrIndex, options) => {
// ...
}); After this PR is merged can the docs be updated to mention this? |
I agree with @mrkjdy that the docs should be updated to reflect these changes. We prefer to do docs updates in tandem with the code updates and then release them together. @xumepadismal Would you mind opening a PR in the cypress-documentation updating the typescript support doc? |
Sorry very busy these days but I'll try to allocate some time till the end of the week to create a PR in the docs |
This is currently breaking the build. The following PR upstream will make this redundant once shipped: cypress-io/cypress#19003
* develop: chore(deps): update dependency ssri to 6.0.2 [security] (#19351) chore: Fix server unit tests running on mac by using actual tmp dir (#19350) fix: Add more precise types to Cypress.Commands (#19003) fix: Do not screenshot or trigger the failed event when tests are skipped (#19331) fix (#19262) fix: throw when writing to 'read only' properties of `config` (#18896) fix: close chrome when closing electron (#19322) fix: disable automatic request retries (#19161) chore: refactor cy funcs (#19080) chore(deps): update dependency @ffmpeg-installer/ffmpeg to v1.1.0 🌟 (#19300)
…cycle * 10.0-release: build: remove syncRemoteGraphQL from codegen chore: fix incorrect type from merge build: allow work with local dashboard (#19376) chore: Test example recipes against chrome (#19362) test(unify): Settings e2e tests (#19324) chore(deps): update dependency ssri to 6.0.2 [security] (#19351) fix: spec from story generation, add deps for install (#19352) chore: Fix server unit tests running on mac by using actual tmp dir (#19350) fix: Add more precise types to Cypress.Commands (#19003) fix: Do not screenshot or trigger the failed event when tests are skipped (#19331) fix (#19262) fix: throw when writing to 'read only' properties of `config` (#18896) fix: close chrome when closing electron (#19322) fix: disable automatic request retries (#19161) chore: refactor cy funcs (#19080) chore(deps): update dependency @ffmpeg-installer/ffmpeg to v1.1.0 🌟 (#19300)
may I ask why the Subject is set to be |
This PR introduces issues with Example: Cypress.Commands.overwrite('visit', (originalFn, urlOrOptions, inputOptions = {}) => {
let options: typeof urlOrOptions; // weird. Typescript doesn't think `urlOrOptions` could be a `string`
// usually these types of guards are type guards, but now this is only a runtime guard
if (typeof urlOrOptions === 'object') {
options = urlOrOptions;
} else {
// wait, `urlOrOptions` is of type `never` here...
options = {url: urlOrOptions, ...inputOptions};
}
return originalFn({
...options,
onBeforeLoad(win) {
options.onBeforeLoad?.(win);
supports(); // prime the ally.js supports cache so it doesn't mess with the cypress-plugin-tab
},
});
}); In this example, |
Also slightly nuanced is the return type of the original function: Cypress.Commands.overwrite('visit', (originalFn, options) => {
const foo = originalFn(options);
return foo
}); In this example, return Cypress.Promise.try(() => {
return originalFn(subject, options)
})
.then(value => {
// value should be `JQuery<HTMLElement>` since the original fn returns a jQuery element
// but `value` is typed as `Cypress.Chainable` since Bluebird cannot unwrap the subject because the way this is typed
// says `originalFn` returns `Cypress.Chainable<Subject>` instead of `Subject` or `Bluebird.Promise<Subject>`
}) The problem is Cypress commands normalized around a |
. |
Cypress.Commands.add
type doesn't take into accountprevSubject
to define the type of the custom command #18940Cypress.Commands.overwrite
typescript problem appearing in 9.1 #19095User facing changelog
prevSubject
variantsoriginalFn
functionPR Tasks
cypress-documentation
?type definitions
?cypress.schema.json
?