I'm trying to overwrite the Cypress within method such that there's an extra argument for the callback.
Ultimately, my goal is to be able to go
cy.customCommandThatSetsAValue().within((subject, extra) => {})
The issue seems to be a matter of timing... whenever I try to pass a non-hardcoded value, it ends up being passed as undefined. I've tried a number of permutations and it seems like somehow even when I set the variable from within a .then() callback, it's undefined when it gets to the custom command.
Here's my override:
function within<Subject>(
originalWithinFn: Cypress.CommandOriginalFnWithSubject<'within', Subject>,
prevSubject: Subject,
optionsOrFn: Partial<Cypress.Loggable> | WithinCallback,
fnOrUndefined?: WithinCallback,
){
let fn: WithinCallback;
let options: Partial<Cypress.Loggable> | undefined;
if (optionsOrFn instanceof Function && fnOrUndefined === undefined) {
fn = optionsOrFn;
} else if (fnOrUndefined instanceof Function) {
options = optionsOrFn;
fn = fnOrUndefined;
} else {
throw new Error('Invalid arguments provided to cy.within');
}
return getMostRecentNavigationShorthand().then(mostRecentShorthand => originalWithinFn(prevSubject, options!, (subject) => fn(subject, mostRecentShorthand)));
}
Cypress.Commands.overwrite('within', within);
A simplified version of customCommandThatSetsAValue() is
return cy.get('foo').then(() => {mostRecentShorthand = anObject});
and
function getMostRecentNavigationShorthand() {
return new Cypress.Promise((resolve, reject) => resolve(mostRecentShorthand));
}
I've tried changing the return in within to
return cy.then(() =>
getMostRecentNavigationShorthand()
.then(mostRecentShorthand =>
originalWithinFn(prevSubject, options!, (subject) => fn(subject, mostRecentShorthand)
)));
as well as trying to wrap a cy.then around the promise (or use that instead of a promise). No matter what i do, it still ends up undefined at actual execution time.
Any idea how/why I keep getting undefined or how to fix it? Thanks!
If I put all that code into a test, it passes. Don't know what
anObjectis, so I just used{abc: 123}.You would not need the
Cypress.Promiseblock since you set the value synchronously, immediately resolve, and never reject. But it does not cause the extra parameter to beundefined. That would only happen if the value ofanObjectwereundefined.