柏树中 "watchPosition" 的存根

Stubbing of "watchPosition" in cypress

我尝试将位置更改注入 JS/REACT-Application。应用程序在 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 发送的值看到位置变化)。

知道要伪造谁的位置变化吗?

有一种不同的方法可以解决触发已注册函数的回调 navigator.geolocation.watchPosition 的问题。问题中的代码试图通过 cy.stub(win.navigator.geolocation, "watchPosition") 来解决这个问题,但这并不能可靠地工作(太快,太晚,不同的 browser/window 上下文,另一个 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;
});