首页 > 解决方案 > 在 Cypress 中键入转义字符在升级后停止工作

问题描述

我将赛普拉斯从 ^3.1.0 更新到 ^3.1.5,并且我有一组 4 个失败的测试。他们都做同样的事情。向 body 元素发送转义,并断言触发了关闭处理程序。这是其中一项测试:

describe('Dialog', () => {
  let closed;
  const onClose = () => {
    closed = true;
  };

  beforeEach(() => {
    closed = false;
    mount(
      <Dialog open onClose={onClose}>
        <div>Test</div>
      </Dialog>
    );
  });

  it('closes when clicking the backdrop', () => {
    cy.get('[data-cy=dialog-backdrop]')
      .click({force: true})
      .then(() => {
         cy.expect(closed).to.equal(true);
      });
  });

  it('closes when pressing the escape key', () => {
    cy.get('body')
      .type('{esc}', {force: true})
      .then(() => {
        cy.expect(closed).to.equal(true);
      });
  });
});

第一次测试通过,第二次测试失败。唯一改变的是升级 jest、babel7 和 cypress。我还应该看什么来解决这个问题?

mount.js

import React from 'react';
import 'react-virtualized/styles.css';
import {MuiThemeProvider, createGenerateClassName, jssPreset} from 
'@material-ui/core/styles';
import {SheetsRegistry} from 'react-jss/lib/jss';
import {create} from 'jss';
import JssProvider from 'react-jss/lib/JssProvider';
import {createMemoryHistory} from 'history';
import {MockedProvider} from 'react-apollo/test-utils';
import {Router} from 'react-router-dom';
import theme from '../../src/theme';
import HistoryProvider from '../../src/components/history';

const stylesCache = new Map();
const sheetsRegistry = new SheetsRegistry();

// NOTE: Copied and modified from https://github.com/bahmutov/cypress-react-unit-test/blob/master/lib/index.js

function getAppIframeHead() {
  const parentDocument = window.parent.document;
  const projectName = Cypress.config('projectName');
  const appIframeId = `Your App: '${projectName}'`;
  const appIframe = parentDocument.getElementById(appIframeId);
  return appIframe.contentDocument.querySelector('head');
}
  const copyStyles = component => {
  const hash = component.type.name;

  let styles = document.querySelectorAll('head style');
  if (styles.length) {
    console.log('injected %d styles', styles.length);
    stylesCache.set(hash, styles);
  } else {
    console.log('No styles injected for this component, checking cache');
  if (stylesCache.has(hash)) {
    styles = stylesCache.get(hash);
  } else {
    styles = null;
  }
}

if (!styles) {
  return;
}

  styles.forEach(style => {
    getAppIframeHead().appendChild(style);
  });
};

function setXMLHttpRequest(w) {
  window.XMLHttpRequest = w.XMLHttpRequest;
  return w;
}

function setAlert(w) {
  window.alert = w.alert;
  return w;
}

function forwardEventListeners(w) {
  window.addEventListener = (...params) => {
    w.addEventListener(...params);
  };
}

function wrapJsx(jsx, mocks, history, styleNode) {
  const generateClassName = createGenerateClassName();
  const jss = create({
    ...jssPreset(),
    insertionPoint: styleNode
  });
  const sheetsManager = new Map();
  return (
  <JssProvider registry={sheetsRegistry} generateClassName= . 
{generateClassName} jss={jss}>
  <MuiThemeProvider theme={theme} sheetsManager={sheetsManager}>
    <MockedProvider mocks={mocks} addTypename={false}>
      <Router history={history}>
        <HistoryProvider>{jsx}</HistoryProvider>
      </Router>
    </MockedProvider>
  </MuiThemeProvider>
</JssProvider>
  );
}

export default (jsx, mocks = []) => {
const html = `<body>
  <div id="app"></div>
  <script src="https://unpkg.com/react@${React.version}/umd/react.development.js"></script>
  <script src="https://unpkg.com/react-dom@${React.version}/umd/react-dom.development.js"></script>
</body>`;

const doc = cy.state('document');
doc.write(html);
doc.close();

const history = createMemoryHistory();
cy.window({log: false})
  .then(setXMLHttpRequest)
  .then(setAlert)
  .then(forwardEventListeners)
  .its('ReactDOM.render')
  .then(render => {
  const styleNode = document.createElement('noscript');
  styleNode.setAttribute('id', 'jss-insertion-point');
  getAppIframeHead().appendChild(styleNode);
  const toRender = wrapJsx(jsx, mocks, history, styleNode);
  render(toRender, doc.getElementById('app'));
  copyStyles(jsx);
  return cy.wrap({history});
});
return {history};
};

包.json

{
  "name": "MyApp",
  "version": "1.0.0",
  "description": "AppInsights",
  "main": "index.js",
  "license": "UNLICENSED",
  "private": true,
  "dependencies": {
    "@babel/core": "^7.0.0",
    "@babel/plugin-proposal-decorators": "^7.0.0",
    "@babel/register": "^7.0.0",
    "@material-ui/core": "^3.0.0",
    "@material-ui/icons": "^3.0.0",
    "apollo-cache-inmemory": "^1.2.10",
    "apollo-client": "^2.4.2",
    "apollo-link-context": "^1.0.9",
    "apollo-link-http": "^1.5.5",
    "axios": "^0.18.0",
    "babel-core": "^7.0.0-bridge.0",
    "babel-jest": "^23.4.2",
    "babel-plugin-dynamic-import-webpack": "^1.0.2",
    "classnames": "^2.2.6",
    "clean-webpack-plugin": "^0.1.19",
    "connected-react-router": "^4.3.0",
    "dotenv": "^6.0.0",
    "dotenv-webpack": "^1.5.5",
    "formik": "^1.5.0",
    "graphql": "^0.13.2",
    "graphql-tag": "^2.9.2",
    "history": "^4.7.2",
    "html-webpack-plugin": "^3.2.0",
    "jest": "^24.1.0",
    "jest-junit": "^5.2.0",
    "jwt-decode": "^2.2.0",
    "lodash": "^4.17.10",
    "material-ui-popup-state": "^1.0.1",
    "mixpanel-browser": "^2.22.4",
    "moment": "^2.22.2",
    "prop-types": "^15.6.2",
    "query-string": "^6.1.0",
    "react": "^16.3.0",
    "react-apollo": "^2.2.4",
    "react-clamp-lines": "^1.1.0",
    "react-dom": "^16.3.0",
    "react-infinite-scroll-component": "^4.2.0",
    "react-router-dom": "^4.2.2",
    "react-text-mask": "^5.4.3",
    "react-virtualized": "^9.21.0",
    "regenerator-runtime": "^0.13.1",
    "uglifyjs-webpack-plugin": "^1.2.5",
    "uuid": "^3.2.1",
    "webfontloader": "^1.6.28",
    "webpack": "^4.9.1",
    "webpack-dev-middleware": "^3.1.3",
    "webpack-hot-middleware": "^2.22.2",
    "webpack-merge": "^4.1.2"
  },
  "devDependencies": {
    "@babel/plugin-proposal-class-properties": "^7.0.0",
    "@babel/plugin-proposal-do-expressions": "^7.0.0",
    "@babel/plugin-proposal-export-default-from": "^7.0.0",
    "@babel/plugin-proposal-export-namespace-from": "^7.0.0",
    "@babel/plugin-proposal-function-bind": "^7.0.0",
    "@babel/plugin-proposal-function-sent": "^7.0.0",
    "@babel/plugin-proposal-json-strings": "^7.0.0",
    "@babel/plugin-proposal-logical-assignment-operators": "^7.0.0",
    "@babel/plugin-proposal-nullish-coalescing-operator": "^7.0.0",
    "@babel/plugin-proposal-numeric-separator": "^7.0.0",
    "@babel/plugin-proposal-optional-chaining": "^7.0.0",
    "@babel/plugin-proposal-pipeline-operator": "^7.0.0",
    "@babel/plugin-proposal-throw-expressions": "^7.0.0",
    "@babel/plugin-syntax-dynamic-import": "^7.0.0",
    "@babel/plugin-syntax-import-meta": "^7.0.0",
    "@babel/plugin-transform-modules-commonjs": "^7.0.0",
    "@babel/plugin-transform-runtime": "^7.3.4",
    "@babel/runtime-corejs2": "^7.3.4",
    "@babel/polyfill": "^7.0.0",
    "@babel/preset-env": "^7.0.0",
    "@babel/preset-react": "^7.0.0",
    "@cypress/webpack-preprocessor": "^3.0.0",
    "babel-eslint": "^9.0.0",
    "babel-loader": "^8.0.0",
    "babel-plugin-dynamic-import-node": "^1.2.0",
    "css-loader": "^2.0.0",
    "cypress": "^3.1.5",
    "eslint": "^4.19.1",
    "eslint-config-airbnb": "^16.1.0",
    "eslint-config-prettier": "^2.9.0",
    "eslint-config-react": "^1.1.7",
    "eslint-plugin-import": "^2.12.0",
    "eslint-plugin-jsx-a11y": "^6.0.3",
    "eslint-plugin-prettier": "^2.6.0",
    "eslint-plugin-react": "^7.8.2",
    "ini": "1.3.5",
    "jss": "^9.8.7",
    "mockdate": "^2.0.2",
    "prettier": "^1.13.0",
    "react-hot-loader": "^4.2.0",
    "react-jss": "^8.6.1",
    "react-test-renderer": "^16.4.0",
    "style-loader": "^0.23.1",
    "webpack-cli": "^3.1.1",
    "webpack-dev-server": "^3.2.1"
  },
  "scripts": {
    "build": "webpack --config webpack.prod.js",
    "dev": "webpack-dev-server --open --config webpack.dev.js",
    "format": "prettier --write --single-quote --print-width=120 --tab-width=2 \"src/js/**/*.{js,jsx,json}\"",
    "lint": "eslint \"**/*.{js,jsx}\"",
    "watch": "webpack --watch --config webpack.dev.js",
    "test": "jest",
    "testWatch": "jest --watch",
    "cy:open": "cypress open",
    "cy:run": "cypress run",
    "cy:verify": "cypress verify"
  },
  "jest": {
    "modulePathIgnorePatterns": [
      "cypress/",
      "__tests__/utils/"
    ],
    "reporters": [
      "default",
      "jest-junit"
    ]
  },
  "jest-junit": {
    "output": "./results/jest/junit.xml"
  }
}

标签: cypress

解决方案


推荐阅读