Преглед изворни кода

Merge pull request #189 from smiclea/cypress-login

Add support for Cypress 'Run All Tests'
Dorin Paslaru пре 8 година
родитељ
комит
d047143b37
23 измењених фајлова са 136 додато и 110 уклоњено
  1. 3 3
      cypress.json
  2. 4 0
      private/cypress/config.template.js
  3. 1 1
      private/cypress/integration/login/Invalid Login.js
  4. 2 5
      private/cypress/integration/migration/1 - Create Openstack Endpoint.js
  5. 2 6
      private/cypress/integration/migration/2 - Create VmWare Endpoint.js
  6. 8 10
      private/cypress/integration/migration/3 - Create VmWare Openstack Migration.js
  7. 3 7
      private/cypress/integration/migration/4 - Cancel first running migration.js
  8. 2 7
      private/cypress/integration/migration/6 - Delete first migration.js
  9. 2 5
      private/cypress/integration/migration/7 - Delete e2e Openstack endpoint.js
  10. 2 5
      private/cypress/integration/migration/8 - Delete e2e VmWare endpoint.js
  11. 2 5
      private/cypress/integration/replica/1 - Create Azure Endpoint.js
  12. 2 6
      private/cypress/integration/replica/2 - Create VmWare Endpoint.js
  13. 9 9
      private/cypress/integration/replica/3 - Create VmWare Azure Replica.js
  14. 3 7
      private/cypress/integration/replica/4 - Cancel first running replica.js
  15. 2 7
      private/cypress/integration/replica/5 - Cannot delete used endpoint.js
  16. 2 7
      private/cypress/integration/replica/6 - Delete first replica.js
  17. 2 5
      private/cypress/integration/replica/7 - Delete e2e Azure endpoint.js
  18. 2 5
      private/cypress/integration/replica/8 - Delete e2e VmWare endpoint.js
  19. 3 8
      private/cypress/integration/scheduler/Scheduler Operations.js
  20. 73 0
      private/cypress/support/commands.js
  21. 2 0
      private/cypress/support/index.js
  22. 4 1
      src/components/atoms/StatusPill/index.jsx
  23. 1 1
      src/components/organisms/DetailsContentHeader/index.jsx

+ 3 - 3
cypress.json

@@ -4,10 +4,10 @@
   "integrationFolder": "private/cypress/integration",
   "pluginsFile": false,
   "screenshotsFolder": "private/cypress/screenshots",
-  "supportFile": false,
   "videosFolder": "private/cypress/videos",
+  "supportFile": "private/cypress/support/index.js",
   "viewportWidth": 1280,
-  "viewportHeight": 660,
-  "defaultCommandTimeout":	7000,
+  "viewportHeight": 900,
+  "defaultCommandTimeout": 7000,
   "execTimeout": 90000
 }

+ 4 - 0
private/cypress/config.template.js

@@ -2,6 +2,7 @@
 
 export default {
   nodeServer: 'http://localhost:3000/',
+  coriolisUrl: '',
   username: 'admin',
   password: '',
   endpoints: {
@@ -31,6 +32,9 @@ export default {
       location: { label: 'West US', value: 'westus' },
       resourceGroup: { label: 'Coriolis', value: 'coriolis' },
     },
+    openstack: {
+      network: 'private',
+    },
     instancesSearch: 'ubuntu',
     instancesSelectItem: 2,
   },

+ 1 - 1
private/cypress/integration/login/Invalid Login.js

@@ -5,7 +5,7 @@ import config from '../../config'
 
 declare var cy: any
 
-describe('Coriolis Login', () => {
+describe('Coriolis Login Failed', () => {
   it('Displays incorrect password', () => {
     cy.server()
     cy.route({ url: '**/identity/**', method: 'POST' }).as('login')

+ 2 - 5
private/cypress/integration/migration/1 - Create Openstack Endpoint.js

@@ -5,14 +5,11 @@ import config from '../../config'
 
 describe('Create Openstack Endpoint', () => {
   before(() => {
-    cy.visit(config.nodeServer)
-    cy.get('input[label="Username"]').type(config.username)
-    cy.get('input[label="Password"]').type(config.password)
-    cy.get('button').click()
+    cy.login()
   })
 
   beforeEach(() => {
-    Cypress.Cookies.preserveOnce('unscopedToken', 'token', 'projectId')
+    Cypress.Cookies.preserveOnce('token', 'projectId')
   })
 
   it('Shows new Openstack endpoint dialog', () => {

+ 2 - 6
private/cypress/integration/migration/2 - Create VmWare Endpoint.js

@@ -5,15 +5,11 @@ import config from '../../config'
 
 describe('Create VmWare Endpoint', () => {
   before(() => {
-    cy.server()
-    cy.visit(config.nodeServer)
-    cy.get('input[label="Username"]').type(config.username)
-    cy.get('input[label="Password"]').type(config.password)
-    cy.get('button').click()
+    cy.login()
   })
 
   beforeEach(() => {
-    Cypress.Cookies.preserveOnce('unscopedToken', 'token', 'projectId')
+    Cypress.Cookies.preserveOnce('token', 'projectId')
   })
 
   it('Shows new VmWare endpoint dialog', () => {

+ 8 - 10
private/cypress/integration/migration/3 - Create VmWare Openstack Migration.js

@@ -5,14 +5,11 @@ import config from '../../config'
 
 describe('Create VmWare to Openstack Migration', () => {
   before(() => {
-    cy.visit(config.nodeServer)
-    cy.get('input[label="Username"]').type(config.username)
-    cy.get('input[label="Password"]').type(config.password)
-    cy.get('button').click()
+    cy.login()
   })
 
   beforeEach(() => {
-    Cypress.Cookies.preserveOnce('unscopedToken', 'token', 'projectId')
+    Cypress.Cookies.preserveOnce('token', 'projectId')
   })
 
   it('Shows Wizard page', () => {
@@ -50,8 +47,8 @@ describe('Create VmWare to Openstack Migration', () => {
   it('Fills Openstack migration info', () => {
     cy.get('button').contains('Next').click()
     cy.get('div').contains('Advanced').click()
-    cy.get('input[placeholder="Floating IP Pool"]').type(config.wizard.openstack.floatingIpPool)
-    cy.get('input[placeholder="Migration Floating IP Pool"]').type(config.wizard.openstack.migrationFloatingIpPool)
+    // cy.get('input[placeholder="Floating IP Pool"]').type(config.wizard.openstack.floatingIpPool)
+    // cy.get('input[placeholder="Migration Floating IP Pool"]').type(config.wizard.openstack.migrationFloatingIpPool)
   })
 
   it('Selects first available network mapping', () => {
@@ -64,7 +61,8 @@ describe('Create VmWare to Openstack Migration', () => {
     cy.get('button').contains('Next').should('be.disabled')
     cy.get('div[data-test-id="networkItem"]').its('length').should('be.gt', 0)
     cy.get('div[value="Select ..."]').first().click()
-    cy.get('div[data-test-id="dropdownListItem"]').first().click()
+    // cy.get('div[data-test-id="dropdownListItem"]').first().click()
+    cy.get('div[data-test-id="dropdownListItem"]').contains(config.wizard.openstack.network).click()
     cy.get('button').contains('Next').should('not.be.disabled')
   })
 
@@ -75,8 +73,8 @@ describe('Create VmWare to Openstack Migration', () => {
     cy.get('#app').should('contain', 'e2e-openstack-test')
     cy.get('#app').should('contain', 'Coriolis Migration')
     cy.get('#app').should('contain', 'Migration Options')
-    cy.get('#app').should('contain', config.wizard.openstack.migrationFloatingIpPool)
-    cy.get('#app').should('contain', config.wizard.openstack.floatingIpPool)
+    // cy.get('#app').should('contain', config.wizard.openstack.migrationFloatingIpPool)
+    // cy.get('#app').should('contain', config.wizard.openstack.floatingIpPool)
     cy.get('#app').should('contain', 'Networks')
     cy.get('#app').should('contain', 'Instances')
   })

+ 3 - 7
private/cypress/integration/migration/4 - Cancel first running migration.js

@@ -1,18 +1,13 @@
 
 // @flow
 
-import config from '../../config'
-
 describe('Cancel a running migration', () => {
   before(() => {
-    cy.visit(config.nodeServer)
-    cy.get('input[label="Username"]').type(config.username)
-    cy.get('input[label="Password"]').type(config.password)
-    cy.get('button').click()
+    cy.login()
   })
 
   beforeEach(() => {
-    Cypress.Cookies.preserveOnce('unscopedToken', 'token', 'projectId')
+    Cypress.Cookies.preserveOnce('token', 'projectId')
   })
 
   it('Cancels migration', () => {
@@ -25,5 +20,6 @@ describe('Cancel a running migration', () => {
     cy.route({ url: '**/actions', method: 'POST' }).as('cancel')
     cy.get('button').contains('Yes').click()
     cy.wait('@cancel')
+    cy.get('div[data-test-id="mainStatusPill-ERROR"]', { timeout: 120000 })
   })
 })

+ 2 - 7
private/cypress/integration/migration/6 - Delete first migration.js

@@ -1,18 +1,13 @@
 
 // @flow
 
-import config from '../../config'
-
 describe('Delete the first migration', () => {
   before(() => {
-    cy.visit(config.nodeServer)
-    cy.get('input[label="Username"]').type(config.username)
-    cy.get('input[label="Password"]').type(config.password)
-    cy.get('button').click()
+    cy.login()
   })
 
   beforeEach(() => {
-    Cypress.Cookies.preserveOnce('unscopedToken', 'token', 'projectId')
+    Cypress.Cookies.preserveOnce('token', 'projectId')
   })
 
   it('Deletes migration', () => {

+ 2 - 5
private/cypress/integration/migration/7 - Delete e2e Openstack endpoint.js

@@ -5,14 +5,11 @@ import config from '../../config'
 
 describe('Delete the Openstack endpoint created for e2e testing', () => {
   before(() => {
-    cy.visit(config.nodeServer)
-    cy.get('input[label="Username"]').type(config.username)
-    cy.get('input[label="Password"]').type(config.password)
-    cy.get('button').click()
+    cy.login()
   })
 
   beforeEach(() => {
-    Cypress.Cookies.preserveOnce('unscopedToken', 'token', 'projectId')
+    Cypress.Cookies.preserveOnce('token', 'projectId')
   })
 
   it('Goes to endpoints page', () => {

+ 2 - 5
private/cypress/integration/migration/8 - Delete e2e VmWare endpoint.js

@@ -5,14 +5,11 @@ import config from '../../config'
 
 describe('Delete the VmWare endpoint created for e2e testing', () => {
   before(() => {
-    cy.visit(config.nodeServer)
-    cy.get('input[label="Username"]').type(config.username)
-    cy.get('input[label="Password"]').type(config.password)
-    cy.get('button').click()
+    cy.login()
   })
 
   beforeEach(() => {
-    Cypress.Cookies.preserveOnce('unscopedToken', 'token', 'projectId')
+    Cypress.Cookies.preserveOnce('token', 'projectId')
   })
 
   it('Goes to endpoints page', () => {

+ 2 - 5
private/cypress/integration/replica/1 - Create Azure Endpoint.js

@@ -5,14 +5,11 @@ import config from '../../config'
 
 describe('Create Azure Endpoint', () => {
   before(() => {
-    cy.visit(config.nodeServer)
-    cy.get('input[label="Username"]').type(config.username)
-    cy.get('input[label="Password"]').type(config.password)
-    cy.get('button').click()
+    cy.login()
   })
 
   beforeEach(() => {
-    Cypress.Cookies.preserveOnce('unscopedToken', 'token', 'projectId')
+    Cypress.Cookies.preserveOnce('token', 'projectId')
   })
 
   it('Shows new Azure endpoint dialog', () => {

+ 2 - 6
private/cypress/integration/replica/2 - Create VmWare Endpoint.js

@@ -5,15 +5,11 @@ import config from '../../config'
 
 describe('Create VmWare Endpoint', () => {
   before(() => {
-    cy.server()
-    cy.visit(config.nodeServer)
-    cy.get('input[label="Username"]').type(config.username)
-    cy.get('input[label="Password"]').type(config.password)
-    cy.get('button').click()
+    cy.login()
   })
 
   beforeEach(() => {
-    Cypress.Cookies.preserveOnce('unscopedToken', 'token', 'projectId')
+    Cypress.Cookies.preserveOnce('token', 'projectId')
   })
 
   it('Shows new VmWare endpoint dialog', () => {

+ 9 - 9
private/cypress/integration/replica/3 - Create VmWare Azure Replica.js

@@ -5,14 +5,11 @@ import config from '../../config'
 
 describe('Create VmWare to Azure Replica', () => {
   before(() => {
-    cy.visit(config.nodeServer)
-    cy.get('input[label="Username"]').type(config.username)
-    cy.get('input[label="Password"]').type(config.password)
-    cy.get('button').click()
+    cy.login()
   })
 
   beforeEach(() => {
-    Cypress.Cookies.preserveOnce('unscopedToken', 'token', 'projectId')
+    Cypress.Cookies.preserveOnce('token', 'projectId')
   })
 
   it('Shows Wizard page', () => {
@@ -49,10 +46,13 @@ describe('Create VmWare to Azure Replica', () => {
 
   it('Fills Azure replica info', () => {
     cy.get('button').contains('Next').click()
-    cy.get('div[data-test-id="dropdown-location"]').first().click()
-    cy.get('div[data-test-id="dropdownListItem"]').contains(config.wizard.azure.location.label).click()
-    cy.get('div[data-test-id="dropdown-resource_group"]').first().click()
-    cy.get('div[data-test-id="dropdownListItem"]').contains(config.wizard.azure.resourceGroup.label).click()
+    cy.get('input[placeholder="Location"]').type(config.wizard.azure.location.value)
+    cy.get('input[placeholder="Resource Group"]').type(config.wizard.azure.resourceGroup.value)
+
+    // cy.get('div[data-test-id="dropdown-location"]').first().click()
+    // cy.get('div[data-test-id="dropdownListItem"]').contains(config.wizard.azure.location.label).click()
+    // cy.get('div[data-test-id="dropdown-resource_group"]').first().click()
+    // cy.get('div[data-test-id="dropdownListItem"]').contains(config.wizard.azure.resourceGroup.label).click()
   })
 
   it('Selects first available network mapping', () => {

+ 3 - 7
private/cypress/integration/replica/4 - Cancel first running replica.js

@@ -1,18 +1,13 @@
 
 // @flow
 
-import config from '../../config'
-
 describe('Cancel a running replica', () => {
   before(() => {
-    cy.visit(config.nodeServer)
-    cy.get('input[label="Username"]').type(config.username)
-    cy.get('input[label="Password"]').type(config.password)
-    cy.get('button').click()
+    cy.login()
   })
 
   beforeEach(() => {
-    Cypress.Cookies.preserveOnce('unscopedToken', 'token', 'projectId')
+    Cypress.Cookies.preserveOnce('token', 'projectId')
   })
 
   it('Cancels replica execution', () => {
@@ -23,5 +18,6 @@ describe('Cancel a running replica', () => {
     cy.route({ url: '**/actions', method: 'POST' }).as('cancel')
     cy.get('button').contains('Yes').click()
     cy.wait('@cancel')
+    cy.get('div[data-test-id="mainStatusPill-ERROR"]', { timeout: 120000 })
   })
 })

+ 2 - 7
private/cypress/integration/replica/5 - Cannot delete used endpoint.js

@@ -1,18 +1,13 @@
 
 // @flow
 
-import config from '../../config'
-
 describe('Cannot delete used endpoint', () => {
   before(() => {
-    cy.visit(config.nodeServer)
-    cy.get('input[label="Username"]').type(config.username)
-    cy.get('input[label="Password"]').type(config.password)
-    cy.get('button').click()
+    cy.login()
   })
 
   beforeEach(() => {
-    Cypress.Cookies.preserveOnce('unscopedToken', 'token', 'projectId')
+    Cypress.Cookies.preserveOnce('token', 'projectId')
   })
 
   it('Should show in usage message when trying to delete', () => {

+ 2 - 7
private/cypress/integration/replica/6 - Delete first replica.js

@@ -1,18 +1,13 @@
 
 // @flow
 
-import config from '../../config'
-
 describe('Delete the first replica', () => {
   before(() => {
-    cy.visit(config.nodeServer)
-    cy.get('input[label="Username"]').type(config.username)
-    cy.get('input[label="Password"]').type(config.password)
-    cy.get('button').click()
+    cy.login()
   })
 
   beforeEach(() => {
-    Cypress.Cookies.preserveOnce('unscopedToken', 'token', 'projectId')
+    Cypress.Cookies.preserveOnce('token', 'projectId')
   })
 
   it('Delete replica', () => {

+ 2 - 5
private/cypress/integration/replica/7 - Delete e2e Azure endpoint.js

@@ -5,14 +5,11 @@ import config from '../../config'
 
 describe('Delete the Azure endpoint created for e2e testing', () => {
   before(() => {
-    cy.visit(config.nodeServer)
-    cy.get('input[label="Username"]').type(config.username)
-    cy.get('input[label="Password"]').type(config.password)
-    cy.get('button').click()
+    cy.login()
   })
 
   beforeEach(() => {
-    Cypress.Cookies.preserveOnce('unscopedToken', 'token', 'projectId')
+    Cypress.Cookies.preserveOnce('token', 'projectId')
   })
 
   it('Goes to endpoints page', () => {

+ 2 - 5
private/cypress/integration/replica/8 - Delete e2e VmWare endpoint.js

@@ -5,14 +5,11 @@ import config from '../../config'
 
 describe('Delete the VmWare endpoint created for e2e testing', () => {
   before(() => {
-    cy.visit(config.nodeServer)
-    cy.get('input[label="Username"]').type(config.username)
-    cy.get('input[label="Password"]').type(config.password)
-    cy.get('button').click()
+    cy.login()
   })
 
   beforeEach(() => {
-    Cypress.Cookies.preserveOnce('unscopedToken', 'token', 'projectId')
+    Cypress.Cookies.preserveOnce('token', 'projectId')
   })
 
   it('Goes to endpoints page', () => {

+ 3 - 8
private/cypress/integration/scheduler/Scheduler Operations.js

@@ -1,18 +1,13 @@
 
 // @flow
 
-import config from '../../config'
-
-describe('Create Azure Endpoint', () => {
+describe('Scheduler Operations', () => {
   before(() => {
-    cy.visit(config.nodeServer)
-    cy.get('input[label="Username"]').type(config.username)
-    cy.get('input[label="Password"]').type(config.password)
-    cy.get('button').click()
+    cy.login()
   })
 
   beforeEach(() => {
-    Cypress.Cookies.preserveOnce('unscopedToken', 'token', 'projectId')
+    Cypress.Cookies.preserveOnce('token', 'projectId')
   })
 
   it('Goes to scheduler\'s page', () => {

+ 73 - 0
private/cypress/support/commands.js

@@ -0,0 +1,73 @@
+// @flow
+
+import config from '../config.js'
+
+const identityUrl = `${config.coriolisUrl}identity/auth/tokens`
+const projectsUrl = `${config.coriolisUrl}identity/auth/projects`
+
+declare var expect: any
+
+Cypress.Commands.add('login', () => {
+  let unscopedBody = {
+    auth: {
+      identity: {
+        methods: ['password'],
+        password: {
+          user: {
+            name: config.username,
+            domain: { name: 'default' },
+            password: config.password,
+          },
+        },
+      },
+      scope: 'unscoped',
+    },
+  }
+
+  cy.request({
+    method: 'POST',
+    url: identityUrl,
+    body: unscopedBody,
+  }).then(unscopedResponse => {
+    let unscopedToken = unscopedResponse.headers['x-subject-token']
+    expect(unscopedToken).to.exist
+
+    cy.request({
+      method: 'GET',
+      url: projectsUrl,
+      headers: { 'X-Auth-Token': unscopedToken },
+    }).then(projectsReponse => {
+      let projectId = projectsReponse.body.projects[0].id
+      expect(projectId).to.exist
+
+      let scopedBody = {
+        auth: {
+          identity: {
+            methods: ['token'],
+            token: {
+              id: unscopedToken,
+            },
+          },
+          scope: {
+            project: {
+              id: projectId,
+            },
+          },
+        },
+      }
+
+      cy.request({
+        method: 'POST',
+        url: identityUrl,
+        body: scopedBody,
+      }).then(scopedResponse => {
+        let scopedToken = scopedResponse.headers['x-subject-token']
+        expect(scopedToken).to.exist
+
+        cy.setCookie('token', scopedToken)
+        cy.setCookie('projectId', projectId)
+        cy.visit(config.nodeServer)
+      })
+    })
+  })
+})

+ 2 - 0
private/cypress/support/index.js

@@ -0,0 +1,2 @@
+// @flow
+import './commands'

+ 4 - 1
src/components/atoms/StatusPill/index.jsx

@@ -102,6 +102,7 @@ type Props = {
   secondary: boolean,
   alert: boolean,
   small: boolean,
+  'data-test-id': string,
 }
 @observer
 class StatusPill extends React.Component<Props> {
@@ -110,6 +111,8 @@ class StatusPill extends React.Component<Props> {
   }
 
   render() {
+    const dataTestId = this.props['data-test-id'] ? this.props['data-test-id'] : `statusPill-${this.props.status || 'null'}`
+
     return (
       <Wrapper
         {...this.props}
@@ -118,7 +121,7 @@ class StatusPill extends React.Component<Props> {
         secondary={this.props.secondary}
         alert={this.props.alert}
         small={this.props.small}
-        data-test-id={`statusPill-${this.props.status || 'null'}`}
+        data-test-id={dataTestId}
       >
         {this.props.label || this.props.status}
       </Wrapper>

+ 1 - 1
src/components/organisms/DetailsContentHeader/index.jsx

@@ -126,7 +126,7 @@ class DetailsContentHeader extends React.Component<Props> {
           primary={this.props.primaryInfoPill}
         />
         <StatusPill
-          data-test-id={`statusPill-${statusLabel || ''}`}
+          data-test-id={`mainStatusPill-${statusLabel || ''}`}
           status={this.getStatus()}
           label={statusLabel || ''}
         />