You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Cypress测试用例执行后如何重置window.location.href

问题背景

测试点击操作后会更新window.location.href的UI组件时,存在测试用例间地址污染问题:

  • 第一个测试用例可正常运行
  • 第二个测试用例启动时,地址为前一个测试中UI修改后的地址,导致用例无法从正确页面启动
  • 测试初始地址为自动生成,不能在测试开头硬编码地址重置,需要可在afterEach钩子中执行的通用重置方案,让浏览器地址恢复到测试启动时的初始状态

现有测试代码

it.only('should send asynchronous analytics event after provider selection click', () => {
    rewire$useFlag(() => true);
    cy.location().then((location) => console.log('window !!'));
    const analyticsAsyncStub = cy.stub().as('sendAnalyticsAsyncStub');
    rewire$sendAnalyticsAsync(analyticsAsyncStub);

    //  hack浏览器检测,保证 provider 选项可正常渲染
    cy.window().then(($window) => {
        console.log('window !!', $window.location.href);
        ($window as any).chrome = {};
        ($window as any).chrome.runtime = {
            sendMessage() {
                'mock function';
            },
        };
    });

    mountFixtureWithProviders({ children: <ProviderSelection flagsConfig={defaultFlags} /> });
    cyGetByTestId('provider--metaMask').click();

    cy.get('@sendAnalyticsAsyncStub').should(
        'have.been.calledWithMatch',
        analyticsUtilsModule.createButtonEvent(ButtonEventName.providerSelectionPressed),
    );
});

mountFixtureWithProviders 函数代码

export const mountFixtureWithProviders = ({
children,
mountInsideVisualMock = true,
setErrorLog = () => ({}),
renderErrorScreens,
}: {
    children: ReactNode;
    mountInsideVisualMock?: boolean;
    setErrorLog?: SetErrorLog;
    renderErrorScreens?: boolean;
}) => {
    const RouterMockedChildren = () => <MemoryRouter>{children}</MemoryRouter>;
    const ProvidedChildren = () =>
        renderErrorScreens ? (
            <DemoAppToRenderErrorMessages>
                <RouterMockedChildren />
            </DemoAppToRenderErrorMessages>
        ) : (
            <LinkUiCoreContext.Provider value={{ setErrorLog, 
imageResizerServiceUrl: DEV_IMAGE_RESIZER_SERVICE_URL }}>
                <RouterMockedChildren />
            </LinkUiCoreContext.Provider>
        );
    return mount(mountInsideVisualMock ? linkPageVisualMock({ 
children: <ProvidedChildren /> }) : <ProvidedChildren />);
};
解决方案

缓存初始地址+afterEach统一重置

在测试套件外层缓存组件测试的默认初始地址,每个用例执行完后自动跳转回初始地址即可,不需要硬编码固定地址:

// 写在describe块的最外层作用域
let initialTestHref;

// 套件首次启动时缓存初始地址
before(() => {
  cy.window().then(win => {
    initialTestHref = win.location.href;
  });
});

// 每个用例执行完成后重置地址
afterEach(() => {
  cy.visit(initialTestHref);
});

说明:Cypress组件测试模式下,cy.visit()支持跳转回内存中的默认测试页地址,不会触发跨域错误。

无历史栈残留的重置方式

如果不希望在浏览器历史栈中留下跳转记录,可以替换为location.replace方法做重置:

afterEach(() => {
  cy.window().then(win => {
    win.location.replace(initialTestHref);
  });
});

补充说明

从提供的挂载函数代码看,组件外层包裹的是React Router的MemoryRouter,正常情况下内存路由不会修改真实浏览器的window.location.href,出现地址污染是因为组件内部直接操作了window.location做跳转,上述全局重置方案不需要修改组件业务逻辑,即可完全隔离用例间的地址影响。

内容的提问来源于stack exchange,提问作者daniel blythe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.03 06:24:32