我尝试将位置更改注入 JS/REACT 应用程序。在 window.navigator.geolocation.watchPosition
注册的应用程序。我的想法是存根“watchPosition”方法来获取回调函数的句柄。然后直接从应用调用回调函数。
喜欢:
const watchPositionFake = (successCallback, errorCallback, options) => {
console.debug("PROXY set callback watchPosition");
originalWatchPositionSuccessCallback = successCallback;
};
cy.visit("/", {
onBeforeLoad(win) {
cy.stub(win.navigator.geolocation, "watchPosition").callsFake(watchPositionFake);
}
});
这不适用于 watchPosition
上的应用程序中的函数注册。但这确实适用于 cypress-step 文件中的函数。 (在 console.log 中工作,根据我通过 originalWatchPositionSuccessCallback
发送的值,我看到位置发生了变化。
知道谁来伪造职位变化吗?
答案 0 :(得分:0)
有一种不同的方法可以解决触发注册函数的回调到 navigator.geolocation.watchPosition
的问题。问题中的代码试图通过 cy.stub(win.navigator.geolocation, "watchPosition")
解决这个问题,但这变得不可靠(太快,太晚,不同的浏览器/窗口上下文,另一个 iframe,...),确切的原因各不相同。
在不修改生产代码的情况下触发注册的 watchPosition 回调的另一种解决方案是 cypress 到 CDP 中未记录的 cypress (v6.2) 自动化接口。
export const setFakePosition = position => {
// https://chromedevtools.github.io/devtools-protocol/tot/Emulation/#method-setGeolocationOverride
console.debug(`cypress::setGeolocationOverride with position ${JSON.stringify(position)}`);
cy.log("**setGeolocationOverride**").then(() =>
Cypress.automation("remote:debugger:protocol", {
command: "Emulation.setGeolocationOverride",
params: {
latitude: position.latitude,
longitude: position.longitude,
accuracy: 50
}
})
);
};
并验证:
let positionLogSpy;
When("vehicle is located in {string}", city => {
const position = cityLocationMap[city];
cy.window()
.then(win => {
const expectedLogMessage = `new position lat: ${position.latitude}, lng: ${position.longitude}`;
positionLogSpy = cy.spy(win.console, "log").withArgs(expectedLogMessage);
})
.then(() => {
setFakePosition(position);
});
});
Then("vehicle has moved to {string}", () => {
expect(positionLogSpy).to.be.called;
});