zoukankan      html  css  js  c++  java
  • [Cypress] install, configure, and script Cypress for JavaScript web applications -- part1

    Despite the fact that Cypress is an application that runs natively on your machine, you can install it and add it as a dependency just like all other dependencies in your package.json file. So let's install Cypress and get our project ready to start end-to-end testing with Cypress.

    install:

    npm i -D cypress

    Run:

    npx cypress open

    It will create some default tests and run the tests.

    Config with eslint:

    npm i -D eslint-plugin-cypress

    Open .eslintrc.js:

    const path = require('path')
    
    module.exports = {
      extends: [
        'kentcdodds',
        'kentcdodds/import',
        'kentcdodds/webpack',
        'kentcdodds/jest',
        'kentcdodds/react',
      ],
      plugins: ['eslint-plugin-cypress'],
      env: {'cypress/globals': true},
      overrides: [
        {
          files: ['**/__tests__/**'],
          settings: {
            'import/resolver': {
              jest: {
                jestConfigFile: path.join(__dirname, './jest.config.js'),
              }
            }
          }
        }
      ]
    }

    Update .gitignore:

    coverage
    node_modules
    dist
    cypress/videos
    cypress/screenshots

    Write the first Cypress Test

    Cypress starts out your project with a ton of tests, let’s remove those and add our first test that verifies our calculator can add two numbers together using the Cypress selector playground and Cypress commands.

    describe('anonymous calculator', () => {
        it('can make calculation', () => {
            cy.visit('http://localhost:8080')
            .get('._2S_Gj6clvtEi-dZqCLelKb > :nth-child(3)') // get 1
            .click()
            .get('._1yUJ9HTWYf2v-MMhAEVCAn > :nth-child(4)') // get +
            .click()
            .get('._2S_Gj6clvtEi-dZqCLelKb > :nth-child(5)') // get 3
            .click()
            .get('._1yUJ9HTWYf2v-MMhAEVCAn > :nth-child(5)') // get =
            .click()
            .get('.mNQM6vIr72uG0YPP56ow5')// get display
            .should('have.text', '4');
        })
    })

    Configure Cypress in cypress.json

    Cypress is fairly simple to configure, but it’s important to optimize our experience in testing Cypress. We’ll configure the baseUrl to make it easier to visit our app and we’ll also move our test files to a folder called e2e to make it more clear what types of tests we want to write with Cypress. We’ll use the cypress.json file, but Cypress can also be configured via command line flags and environment variables.

    // cypress.json
    
    {
        "baseUrl": "http://localhost:8080",
        "integrationFolder": "cypress/e2e/",
        "viewportHeight": 900,
        "viewportWidth": 400,
        "defaultCommandTimeout": 5000
    }

    We have config the 'baseUrl', so in the test, we can use:

    describe('anonymous calculator', () => {
        it('can make calculation', () => {
            cy.visit('/')
            .get('._2S_Gj6clvtEi-dZqCLelKb > :nth-child(3)')
            .click()
            .get('._1yUJ9HTWYf2v-MMhAEVCAn > :nth-child(4)')
            .click()
            .get('._2S_Gj6clvtEi-dZqCLelKb > :nth-child(5)')
            .click()
            .get('._1yUJ9HTWYf2v-MMhAEVCAn > :nth-child(5)')
            .click()
            .get('.mNQM6vIr72uG0YPP56ow5')
            .should('have.text', '4');
        })
    })

    Installing cypress-testing-library

    Our selectors are pretty ridiculous, mostly because we’re using CSS-in-JS and css modules for our react application. But even if we weren’t, using class names as selectors for our application testing is pretty brittle and not really testing in the way a user would. So instead let’s use cypress-testing-library to improve our selectors and make it easier to read our tests.

    The following part of code is really hard to read and maintain because those wired selector

    .get('._2S_Gj6clvtEi-dZqCLelKb > :nth-child(3)')
            .click()
            .get('._1yUJ9HTWYf2v-MMhAEVCAn > :nth-child(4)')
            .click()
            .get('._2S_Gj6clvtEi-dZqCLelKb > :nth-child(5)')
            .click()
            .get('._1yUJ9HTWYf2v-MMhAEVCAn > :nth-child(5)')
            .click()
            .get('.mNQM6vIr72uG0YPP56ow5')

    To solve the problem, let's install:

    npm i -D cypress-testing-library

    Inside cypress/support:

    // ***********************************************************
    // This example support/index.js is processed and
    // loaded automatically before your test files.
    //
    // This is a great place to put global configuration and
    // behavior that modifies Cypress.
    //
    // You can change the location of this file or turn off
    // automatically serving support files with the
    // 'supportFile' configuration option.
    //
    // You can read more here:
    // https://on.cypress.io/configuration
    // ***********************************************************
    
    import 'cypress-testing-library/add-commands'
    
    // Import commands.js using ES2015 syntax:
    import './commands'
    
    // Alternatively you can use CommonJS syntax:
    // require('./commands')

    Update the tests:

          cy.visit('/')
            .getByText(/^1$/)
            .click()
            .getByText(/^+$/)
            .click()
            .getByText(/^3$/)
            .click()
            .getByText(/^=$/)
            .click()

    For the display, we need to use 'data-testid':

    Update the component:

        return (
          <div
            className={styles.autoScalingText}
            style={{transform: `scale(${scale},${scale})`}}
            ref={this.node}
            data-testid="total"
          >
            {this.props.children}
          </div>

    Now the test looks like:

    describe('anonymous calculator', () => {
        it('can make calculation', () => {
            cy.visit('/')
            .getByText(/^1$/)
            .click()
            .getByText(/^+$/)
            .click()
            .getByText(/^3$/)
            .click()
            .getByText(/^=$/)
            .click()
            .getByTestId('total')
            .should('have.text', '4');
        })
    })

    Scripting Cypress for local development and Continuous Integration

    We want to make starting cypress as simple as possible for local development and we need to be able to run a single script that exits when the tests are complete for continuous integration. So let’s add a few scripts to get ourselves setup for this development experience.

    Install:

    npm install --save-dev start-server-and-test

    When we run e2e test, check if it is CI, when we run:

    cypress run // not open the broswer

    Otherwise: 

    cypress open

    Then we want to run our server first, after get response from server, then we want to run cypress automaticlly:

    start-server-and-test start http://localhost:8080 cy:run  // run 'start' first, it will start the server wait response from 'http://localhost:8080', if get the response, then run cy:run' command

    Scripts:

    "scripts": {
        "test": "is-ci "test:coverage" "test:watch"",
        "test:coverage": "jest --coverage",
        "test:watch": "jest --watch",
        "test:debug": "node --inspect-brk ./node_modules/jest/bin/jest.js --runInBand --watch",
        "cy:run": "cypress run",
        "cy:open": "cypress open",
        "pretest:e2e:run": "npm run build",
        "test:e2e": "is-ci "test:e2e:run" "test:e2e:dev",
        "test:e2e:run": "start-server-and-test start http://localhost:8080 cy:run",
        "test:e2e:dev": "start-server-and-test dev http://localhost:8080 cy:open",
        "dev": "webpack-serve",
        "build": "webpack --mode=production",
        "precommit": "lint-staged",
        "postbuild": "cp ./public/index.html ./dist/index.html",
        "start": "serve --no-clipboard --listen 8080 dist",
        "lint": "jest --config test/jest-lint.js",
        "format": "prettier "**/*.js" --write",
        "validate": "npm run test &&  && npm run test:e2e:run",
        "setup": "npm run setup && npm run validate"
      },

    Debug a test with Cypress

    One of the greatest features of Cypress is how awesome the experience of debugging tests is. You do have to get used to the asynchronous nature of E2E testing, but once you get the hang of that debugging is pretty straightforward, and the ability to debug your own source code is awesome. The fact that your test and source code are executed in the same context also gives you some powerful advantages as well. You can potentially even expose some internal state to your Cypress app.

    The way to add a debugger in the Cypress:

    describe('anonymous calculator', () => {
        it('can make calculation', () => {
            cy.visit('/')
            .getByText(/^1$/)
            .click()
            .getByText(/^+$/)
            .click()
            .getByText(/^3$/)
            .click()
            .getByText(/^=$/)
            .then(subject => {
                debugger
                return subject;
            })
            .click()
            .getByTestId('total')
            .should('have.text', '4');
        })
    })

     or 

    .getByText(/^=$/)
      .debug()
      .click()

    And

    we can add cy.log('xxx'):

    cy.log('get by text')
    cy.getByText(/^=$/)
       .debug()
        .click()

    In the component, you can also put a debugger:

    ReactDOM.render(
      <Component initialState={{}}>
        {({state, setState}) => {
          debugger
          if(window.Cypress) {
            window.appState = state
            window.setAppState = setState
          }
  • 相关阅读:
    OPENC函数 UF_CSYS UF_MTX UF_VEC (判断矢量平行)(UF_VEC3_is_parallel)
    OPENC函数 UF_CUTTER UF_NCGROUP UF_PARAM(如何创建刀具)(UF_CUTTER_create)
    OPENC函数 (UF_setup UF_ncgroup UF_oper)(创建程序组并创建程序,然后把程序放入组中)(UF_OPER_create)
    OPENC函数 UF_CAM UF_NCGROUP (UF_CAM_opt_ask_types UF_CAM_opt_ask_subtypes UF_NCPROG_create UF_NCGROUP_accept_member)
    OPENC函数UF_UI_ONT UF_OPER (过切检查) (UF_OPER_is_path_gouged)
    OPENC函数 UF_SETUP UF_NCGROUP(获取CAM模块中 程序 机床 几何 加工方法的所有名称)(UF_SETUP_ask_geom_root UF_SETUP_ask_program_root)
    OPENC函数 UF_UI_ONT UF_OPER函数(对当前程序进行操作(获取名称))(UF_UI_ONT_ask_selected_nodes、UF_OPER_ask_cutter_group等)
    OPENC函数 UF_TRNS(平移 变换)( uf5943 , uf5947)
    openstackM版本安装
    openstack及组件简要介绍
  • 原文地址:https://www.cnblogs.com/Answer1215/p/10050934.html
Copyright © 2011-2022 走看看