英文:
Custom command and 'extra data' that ends up as undefined
问题
我正在尝试重写Cypress的within
方法,以便为回调函数添加一个额外的参数。
最终,我的目标是能够执行以下操作:
cy.customCommandThatSetsAValue().within((subject, extra) => {})
问题似乎涉及到时间控制...每当我尝试传递一个非硬编码的值时,它最终被传递为undefined。我尝试了多种排列组合,似乎无论我如何在.then()
回调内设置变量,当它传递到自定义命令时,它都变成了undefined。
这是我的重写代码:
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);
customCommandThatSetsAValue()
的简化版本如下:
return cy.get('foo').then(() => {mostRecentShorthand = anObject});
以及
function getMostRecentNavigationShorthand() {
return new Cypress.Promise((resolve, reject) => resolve(mostRecentShorthand));
}
我尝试将within
中的返回值更改为:
return cy.then(() =>
getMostRecentNavigationShorthand()
.then(mostRecentShorthand =>
originalWithinFn(prevSubject, options!, (subject) => fn(subject, mostRecentShorthand)
)));
还尝试将cy.then
包装在promise周围(或使用它代替promise)。无论我做什么,它最终都在实际执行时变成了undefined。
你有没有想法为什么我一直得到undefined,或者如何修复它?谢谢!
英文:
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!
答案1
得分: 3
如果我把所有的代码都放到一个测试中,它会通过。不知道anObject
是什么,所以我只是使用了{abc: 123}
。
let mostRecentShorthand = null
function getMostRecentNavigationShorthand() {
return new Cypress.Promise((resolve, reject) => resolve(mostRecentShorthand));
}
function within(originalWithinFn, prevSubject, optionsOrFn, fnOrUndefined) {
// 参数解析
return getMostRecentNavigationShorthand()
.then(mostRecentShorthand => {
return originalWithinFn(prevSubject, options, (subject) =>
fn(subject, mostRecentShorthand)
)
})
}
Cypress.Commands.overwrite('within', within)
Cypress.Commands.add('customCommandThatSetsAValue', () => {
return cy.get('h1').then(() => {mostRecentShorthand = {abc: 123}})
})
it('gives an extra parameter to within', () => {
cy.visit('https://example.com');
cy.customCommandThatSetsAValue().within((subject, extra) => {
expect(extra).to.deep.eq({abc: 123})
})
})
你不需要Cypress.Promise
块,因为你是同步设置了这个值,立即解析,而且从未拒绝。但这并不会导致额外的参数为undefined
。只有当anObject
的值为undefined
时才会发生这种情况。
英文:
If I put all that code into a test, it passes. Don't know what anObject
is, so I just used {abc: 123}
.
let mostRecentShorthand = null
function getMostRecentNavigationShorthand() {
return new Cypress.Promise((resolve, reject) => resolve(mostRecentShorthand));
}
function within(originalWithinFn, prevSubject, optionsOrFn, fnOrUndefined) {
// parameter resolving
return getMostRecentNavigationShorthand()
.then(mostRecentShorthand => {
return originalWithinFn(prevSubject, options, (subject) =>
fn(subject, mostRecentShorthand)
)
})
}
Cypress.Commands.overwrite('within', within)
Cypress.Commands.add('customCommandThatSetsAValue', () => {
return cy.get('h1').then(() => {mostRecentShorthand = {abc: 123}})
})
it('gives an extra parameter to within', () => {
cy.visit('https://example.com');
cy.customCommandThatSetsAValue().within((subject, extra) => {
expect(extra).to.deep.eq({abc: 123})
})
})
You would not need the Cypress.Promise
block since you set the value synchronously, immediately resolve, and never reject. But it does not cause the extra parameter to be undefined
. That would only happen if the value of anObject
were undefined
.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论