Skip to content

Commit

Permalink
test/max e2e (#910)
Browse files Browse the repository at this point in the history
* feat: ✨ add g cypress cmd

* refactor: 🎨  add access example in routes

* feat: ✨ add e2e test

* test(max-e2e): 👷 add e2e action

* chore: ✏️ port typo

* chore: ✏️ set port env

* build(max-e2e): 👷 add windows os in e2e action

* fix: 🐛  layout path unescaped in windows

* fix(e2e): 🐛 windows cypress binary is missing

* fix: 🐛 window actions failure

* fix: 🐛 fix merge error

* refactor: 🎨 meaningfull test case title

Co-authored-by: pshu <pishu.spf@antfin.com>
  • Loading branch information
2 people authored and sorrycc committed Jun 23, 2022
1 parent c5bb832 commit 295d494
Show file tree
Hide file tree
Showing 14 changed files with 701 additions and 1,110 deletions.
67 changes: 67 additions & 0 deletions .github/workflows/e2e.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
name: e2e-cypress

env:
NODE_OPTIONS: --max-old-space-size=6144

on:
push:
branches:
- master
paths-ignore:
- 'docs/**'
- '**/*.md'
pull_request:
types:
- 'opened'
- 'synchronize'
workflow_dispatch:

concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true

jobs:
build:
runs-on: ${{ matrix.os }}
strategy:
matrix:
node-version: [16.x]
os: [ubuntu-latest, windows-latest]
fail-fast: false
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0

- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
registry-url: 'https://registry.npmjs.org/'

- name: Setup Global Cypress-cache-folder in Windows
if: matrix.os == 'windows-latest'
run: echo "CYPRESS_CACHE_FOLDER=${HOME}\.cache\Cypress" >> $env:GITHUB_ENV

- name: Install pnpm
uses: pnpm/action-setup@v2.2.2
with:
run_install: false

- name: Install dependencies
run: pnpm i

- name: Build example-max
run: pnpx umi-scripts turbo --cmd build --filter ./examples/max...

- uses: cypress-io/github-action@v4
with:
start: pnpm run preview
wait-on: 'http://127.0.0.1:9527'
command: pnpm run e2e
browser: chrome
working-directory: ./examples/max
install: false
install-command: pnpm i cypress
env:
PORT: 9527
3 changes: 3 additions & 0 deletions examples/max/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,6 @@
/config/config.local.js
/src/.umi
/.umi

/cypress/screenshots
/cypress/videos
17 changes: 16 additions & 1 deletion examples/max/.umirc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,27 @@ export default defineConfig({
name: 'index',
},
{ path: '/users', icon: 'SmileFilled', component: 'users', name: 'users' },
{
path: '/accessAllow',
icon: 'SmileFilled',
component: 'users',
name: 'Allow',
access: 'canReadFoo',
},
{
path: '/accessDeny',
icon: 'SmileFilled',
component: 'users',
name: 'Deny',
access: 'canReadBar',
},
{ path: '/users', icon: 'SmileFilled', component: 'users', name: 'users' },
{ path: '/app1/*', icon: 'SmileFilled', name: 'app1', microApp: 'app1' },
{
path: '/data-flow',
component: 'data-flow',
name: 'data-flow',
icon: 'https://gw.alipayobjects.com/mdn/prod_resou/afts/img/A*CUIoT4xopNYAAAAAAAAAAABkARQnAQ',
icon: 'SmileFilled',
routes: [
{
path: '/data-flow/use-model',
Expand Down
1 change: 1 addition & 0 deletions examples/max/access.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export default function () {
return {
canReadFoo: true,
canReadBar: false,
};
}
12 changes: 12 additions & 0 deletions examples/max/cypress.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { defineConfig } from 'cypress';

const PORT = process.env.PORT || '8000';

export default defineConfig({
e2e: {
setupNodeEvents(on, config) {
// implement node event listeners here
},
baseUrl: `http://localhost:${PORT}`,
},
});
16 changes: 16 additions & 0 deletions examples/max/cypress/e2e/access.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/// <reference types="cypress" />

describe('access', function () {
it('show accessible content no denied', () => {
cy.visit('/');
cy.contains('Allow');
cy.get('Deny').should('not.exist');
});

it('can not visit denied url', () => {
cy.visit('/accessDeny');

cy.contains('403');
cy.contains('抱歉,你无权访问该页面');
});
});
30 changes: 30 additions & 0 deletions examples/max/cypress/e2e/data-flow.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/// <reference types="cypress" />

describe('data-flow', function () {
context('dva', () => {
beforeEach(() => {
cy.visit('/data-flow/dva');
});

it('run count model', () => {
cy.contains('count: 0');

cy.get('button').contains('+').click();

cy.contains('count: 1');
});
});

context('use-model', () => {
beforeEach(() => {
cy.visit('/data-flow/use-model');
});

it('render data from use-model', () => {
cy.get('.ant-layout-content').within(() => {
cy.get('li').contains('foo');
cy.get('li').contains('bar');
});
});
});
});
43 changes: 43 additions & 0 deletions examples/max/cypress/e2e/smoke.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/// <reference types="cypress" />

describe('Basic Test', () => {
beforeEach(() => {
// 每个测试用例都会先执行一次 `cy.visit(url)` 访问的页面, url 根据测试内容决定
// 脚手架中已经配置了 baseUrl, 可以直接写 path 部分, PORT 部分可以通过环境变量 PORT 来控制
cy.visit('/');
});

it('display page normallly', () => {
// 页面正常渲染
cy.contains('index page');

// antd 组件存在
cy.get('button').contains('Button');
cy.get('input.ant-input').should('have.attr', 'type', 'text');
cy.get('div.ant-picker').find('input');
});

it('use pro-layout and render menus', () => {
// layout 存在
cy.contains('Ant Design Pro');

cy.get('li.ant-pro-menu-item').contains('Index');
cy.get('li.ant-pro-menu-item').contains('users');
cy.get('li.ant-pro-menu-item').contains('app1');
cy.get('li.ant-pro-menu-submenu').contains('data-flow');
});

it('render sub-menu', () => {
cy.get('li.ant-pro-menu-submenu').contains('data-flow').click();

cy.get('li.ant-pro-menu-item').contains('use-model');
cy.get('li.ant-pro-menu-item').contains('dva');
});

it('can change local', () => {
cy.get('.ant-dropdown-trigger').find('i.anticon').click();

cy.contains('简体中文').click();
cy.get('li.ant-pro-menu-item').contains('首页');
});
});
5 changes: 5 additions & 0 deletions examples/max/cypress/fixtures/example.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"name": "Using fixtures to represent data",
"email": "hello@cypress.io",
"body": "Fixtures are a great way to mock data for responses to routes"
}
37 changes: 37 additions & 0 deletions examples/max/cypress/support/commands.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/// <reference types="cypress" />
// ***********************************************
// This example commands.ts shows you how to
// create various custom commands and overwrite
// existing commands.
//
// For more comprehensive examples of custom
// commands please read more here:
// https://on.cypress.io/custom-commands
// ***********************************************
//
//
// -- This is a parent command --
// Cypress.Commands.add('login', (email, password) => { ... })
//
//
// -- This is a child command --
// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
//
//
// -- This is a dual command --
// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
//
//
// -- This will overwrite an existing command --
// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
//
// declare global {
// namespace Cypress {
// interface Chainable {
// login(email: string, password: string): Chainable<void>
// drag(subject: string, options?: Partial<TypeOptions>): Chainable<Element>
// dismiss(subject: string, options?: Partial<TypeOptions>): Chainable<Element>
// visit(originalFn: CommandOriginalFn, url: string, options: Partial<VisitOptions>): Chainable<Element>
// }
// }
// }
20 changes: 20 additions & 0 deletions examples/max/cypress/support/e2e.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// ***********************************************************
// This example support/e2e.ts 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 commands.js using ES2015 syntax:
import './commands';

// Alternatively you can use CommonJS syntax:
// require('./commands')
7 changes: 7 additions & 0 deletions examples/max/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@
"private": true,
"scripts": {
"build": "max build",
"ci": "cypress run",
"dev": "max dev",
"e2e": "cypress run",
"e2e:ci": "start-server-and-test preview http://127.0.0.1:9527 e2e",
"preview": "max preview --port 9527",
"start": "npm run dev"
},
Expand All @@ -12,5 +15,9 @@
"@umijs/max": "4.0.0-rc.24",
"react": "18.1.0",
"react-dom": "18.1.0"
},
"devDependencies": {
"cypress": "^10.0.0",
"start-server-and-test": "^1.0.0"
}
}
2 changes: 1 addition & 1 deletion packages/plugins/src/layout.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export default (api: IApi) => {
return dirname(require.resolve('@ant-design/pro-layout/package.json'));
};

const pkgPath = getPkgPath();
const pkgPath = winPath(getPkgPath());

api.modifyAppData((memo) => {
const version = require(`${pkgPath}/package.json`).version;
Expand Down
Loading

0 comments on commit 295d494

Please sign in to comment.