cypress 中“watchPosition”的存根

时间:2021-01-08 12:36:14

标签: javascript cypress cypress-cucumber-preprocessor

我尝试将位置更改注入 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 发送的值,我看到位置发生了变化。

知道谁来伪造职位变化吗?

1 个答案:

答案 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;
});