uniquejava / blog

My notes regarding the vibrating frontend :boom and the plain old java :rofl.
Creative Commons Zero v1.0 Universal
11 stars 5 forks source link

cypress #231

Open uniquejava opened 6 years ago

uniquejava commented 6 years ago

Vue cli cypress plugin Learn TDD in Vue

End-To-End Testing A VueJS HackerNews Clone

vue cli 3 Quick Start Vue.js With Cypress End-To-End Testing For Beginners

API文档

全局安装(可选)

npm install -g cypress
cypress install
cypress run

用法

vue add @vue/e2e-cypress
npx vue-cli-service serve --mode production
npm run test:e2e -- --url http://localhost:8080/
npm run test:e2e -- --url http://localhost:8080/ --headless

Spec编写

tests/e2e/specs/login_spec.js

// https://docs.cypress.io/api/introduction/api.html

describe('Login Test', () => {
  it('Should login and logout.', () => {
    cy.visit('/');
    cy.title().should('eq', 'vue-sidemenu');

    // enter username and password
    cy.get('input[type=text]')
      .clear()
      .type('admin');
    cy.get('input[type=password]').type('admin');

    // login
    cy.get('.btn-login').click();

    // dashboard page click logout button
    cy.get('.el-dropdown-link.home_userinfo').click();
    cy.get('.el-dropdown-menu__item')
      .contains('Logout')
      .click();

    // confirm to logout
    cy.get('.el-message-box__btns > button')
      .eq(1)
      .contains('OK')
      .click();

    // back to login page
    cy.get('.btn-login').should('be.visible');
  });
});
uniquejava commented 6 years ago

cypress自定义task

比如mock mqtt的任务可以定义成task, 不能直接写在spec里.

定义task.(e2e/plugins/index.js)

// https://docs.cypress.io/guides/guides/plugins-guide.html

const mocker = require('../../../mocker');
module.exports = (on, config) => {
  on('task', {
    carryBricks(amount) {
      return new Promise((resolve, reject) => {
        mocker
          .connect()
          .then(() => {
            // cypress:  You must return a promise, a value, or null to indicate that the task was handled.
            resolve(null);
          })
          .catch(err => {
            console.log(err);
            reject(err);
          });
      });
    }
  });

使用自定义的task(e2e/specs/xxx.spec.js)

  it('should carry as many bricks as you can', () => {
    cy.task('carryBricks', 100000000);
    cy.wait(5000);
    cy.get('.you-win').should('be.visible');
  });

测试用例中使用ES7语法(async/await)

cypress的spec中不识别async, 报如下错误

Uncaught ReferenceError: regeneratorRuntime is not defined

This error originated from your test code, not from Cypress.

When Cypress detects uncaught errors originating from your test code it will automatically fail the current test.

解决办法 https://github.com/NicholasBoll/cypress-promise#readme

If you get errors like "regeneratorRuntime is not defined.", you'll have to install babel-polyfill and add import 'babel-polyfill' to your cypress/support/index.

解决办法 https://github.com/cypress-io/cypress/issues/343

uniquejava commented 6 years ago

cypress处理外部请求

cypress在页面完全加载之前, 会一直等待. 如果页面上比如要访问google font什么的请求, 需要等30s然后timeout. 对于中国用户来说, 体验很差.

解决办法: 这些无关痛痒的请求完全可以屏蔽, 有三种方法

cypress 设置http proxy.

比如要访问youtube, cypress默认不会使用系统代理. 见https://github.com/cypress-io/cypress/issues/672 https://github.com/cypress-io/cypress/issues/1469#issue-305961859 解决办法是在你的.zshrc中加入如下

export HTTP_PROXY=http://xxx.com:8080
export HTTPS_PROXY=http://xxx.com:8080
export NO_PROXY=localhost

或者直接在命令行添加NO_PROXY=localhost cypress run

代理的设置参考了这里的脚本https://gist.github.com/timothystone/6453449a56e126b6ad3344c4d43451b1 写得很全面.

不好用. 然后又尝试了在e2e/plugins/index.js中添加如下配置(被我注释掉的部分)

  return Object.assign({}, config, {
    env: {
      // http_proxy: 'http://xxxcom:8080',
      // https_proxy: 'http://xxx.com:8080',
      // http_proxy: 'socks5://127.0.0.1:1080',
      // https_proxy: 'socks5://127.0.0.1:1080',
      // no_proxy: 'localhost,192.168.1.666'
    },
    blacklistHosts: '*.youtube.com',
    fixturesFolder: 'tests/e2e/fixtures',
    integrationFolder: 'tests/e2e/specs',
    screenshotsFolder: 'tests/e2e/screenshots',
    videosFolder: 'tests/e2e/videos',
    supportFile: 'tests/e2e/support/index.js'
  });

不好用.

cypress 设置stub

route中可以传的参数详见: https://docs.cypress.io/guides/guides/network-requests.html

  it('should login in success with correct user', () => {
    cy.server();
    cy.route({
      method: 'GET',
      url: 'https://www.youtube.com/iframe_api',
      status: 404
    });

不好用.

cypress 屏蔽外部网站

在e2e/plugins/index.js中加上blacklistHosts: '*.youtube.com',, 完美解决

详见: https://docs.cypress.io/guides/references/configuration.html#blacklistHosts

uniquejava commented 6 years ago

cypress不支持多窗口

see https://github.com/cypress-io/cypress/issues/590