currents-dev / cypress-cloud

Debug, troubleshoot and record Cypress CI tests in Cloud
https://currents.dev
Other
47 stars 16 forks source link

Focus Resetting with Cypress --record Flag Enabled #213

Closed Selinaqianli closed 1 month ago

Selinaqianli commented 2 months ago

Please confirm

Environment information

``` # Put output below this line System: OS: Linux 6.8 Ubuntu 22.04.5 LTS 22.04.5 LTS (Jammy Jellyfish) CPU: (2) x64 AMD EPYC 7763 64-Core Processor Memory: 6.69 GB / 7.75 GB Container: Yes Shell: 5.1.16 - /bin/bash Binaries: Node: 18.20.4 - /opt/hostedtoolcache/node/18.20.4/x64/bin/node Yarn: 1.22.22 - /usr/local/bin/yarn npm: 10.8.3 - ~/work/verily1/verily1/node_modules/.bin/npm Browsers: Chrome: 128.0.6613.137 Chromium: 128.0.6613.0 npmPackages: @rollup/plugin-commonjs: ^21.0.1 => 21.1.0 @rollup/plugin-node-resolve: ^13.0.6 => 13.3.0 @rollup/plugin-typescript: ^8.3.0 => 8.5.0 @testing-library/dom: ^8.20.0 => 8.20.1 (10.4.0) @testing-library/react: ^[15](https://github.com/verily-src/verily1/actions/runs/10961100269/job/30437234793?pr=36790#step:6:16).0.6 => 15.0.7 @testing-library/user-event: ^14.4.3 => 14.5.2 chalk: ^5.2.0 => undefined (4.1.2) react-i18next: ^14.1.0 => 14.1.3 rollup: ^2.60.0 => 2.79.1 rollup-plugin-dts: ^4.0.1 => 4.2.3 npmGlobalPackages: corepack: 0.28.0 npm: 10.7.0 ```

Describe the bug

I'm encountering an issue with keyboard focus when running tests in Cypress with the --record flag enabled. If there is no next focusable item when pressing Tab, the focus unexpectedly resets back to the first focusable item. This behaviour only happens when the --record flag is turned on.

Test:

import { Button, Stack } from '@mui/material';
import { mount } from 'cypress/react18';

describe('MUI Button Keyboard Focus Test', () => {
  beforeEach(() => {
    // Mount MUI buttons directly
    mount(
      <Stack direction='column' spacing={2}>
        <Button>First Button</Button>
        <Button>Second Button</Button>
        <Button>Third Button</Button>
      </Stack>
    );
    cy.get('button').as('button').first().focus();
  });

  it('should not reset focus to the first button when pressing Tab on the last button', () => {
    cy.get('@button').first().should('be.focused');

    // Press Tab and check the focus moves to the second button
    cy.realPress('Tab');
    cy.get('@button').first().should('not.be.focused');
    cy.get('@button').eq(1).should('be.focused');

    // Press Tab again and check the focus moves to the third button
    cy.realPress('Tab');
    cy.get('@button').eq(1).should('not.be.focused');
    cy.get('@button').eq(2).should('be.focused');

    // Press Tab on the last button and ensure the focus doesn't reset to the first button
    cy.realPress('Tab');

    // Verify that none of the buttons have focus after pressing Tab on the last button
    cy.get('@button').should('not.be.focused');
  });
});

https://github.com/user-attachments/assets/0851f7c9-1b3e-4c83-a65e-2b97e850fa72

Expected behavior

I should move forward between elements and remove focus when no more focusable items are available.

https://github.com/user-attachments/assets/0d6f7e54-d39c-49f2-9290-a42636e1b583

Setup and Command

Command: cypress run --component --record -e TAGS='not @manual'

import {addCucumberPreprocessorPlugin} from '@badeball/cypress-cucumber-preprocessor';
import {createRollupPlugin} from '@badeball/cypress-cucumber-preprocessor/rollup';
import {devServer} from '@cypress/vite-dev-server';
import {viteCommonjs} from '@originjs/vite-plugin-commonjs';
import react from '@vitejs/plugin-react';
import {defineConfig} from 'cypress';

export default defineConfig({
  component: {
    specPattern: '**/*.feature',
    projectId: '1wb9vw', // For cypress enterprise and recording capabilities.
    devServer(devServerConfig) {
      return devServer({
        ...devServerConfig,
        framework: 'react',
        viteConfig: {
          plugins: [
            react(),
            createRollupPlugin(devServerConfig.cypressConfig),
            viteCommonjs(),
          ],
        },
      });
    },
    async setupNodeEvents(on, config) {
      // This is required for the preprocessor to be able to generate JSON reports after each run, and more.
      await addCucumberPreprocessorPlugin(on, config);

      // Make sure to return the config object as it might have been modified by the plugin.
      return config;
    },
  },
  retries: {
    // Configure retry attempts for `cypress run`.
    runMode: 1,
    // Configure retry attempts for `cypress open`.
    openMode: 0,
  },
  video: true,
  viewportWidth: 1280,
  viewportHeight: 1024,
});

Full log and debug output

``` // Put your logs below this line Timed out retrying after 4000ms: expected '[ , 2 more... ]' not to be 'focused' ```