Browse Source

test(cypress): rest & graphql

Signed-off-by: Pranav C <pranavxc@gmail.com>
pull/510/head
Pranav C 3 years ago
parent
commit
2f2adabd06
  1. 2
      .github/workflows/ci-cd.yml
  2. 98
      cypress/integration/app_gql_api_project_spec.js
  3. 5
      cypress/integration/app_rest_api_project_spec.js
  4. 21
      cypress/integration/graphql/create_table_spec.js
  5. 27
      cypress/integration/graphql/open_existing_table_spec.js
  6. 34
      cypress/integration/graphql/open_existing_table_with_m2m_spec.js
  7. 21
      cypress/integration/rest/create_table_spec.js
  8. 27
      cypress/integration/rest/open_existing_table_spec.js
  9. 34
      cypress/integration/rest/open_existing_table_with_m2m_spec.js
  10. 84
      cypress/support/commands.js
  11. 4
      docker-compose-cypress.yml
  12. 6
      packages/nc-gui/components/ProjectTreeView.vue
  13. 14882
      packages/nc-gui/package-lock.json
  14. 6
      packages/nc-gui/pages/projects/index.vue
  15. 18
      packages/nocodb/package-lock.json

2
.github/workflows/ci-cd.yml

@ -18,7 +18,7 @@ jobs:
uses: cypress-io/github-action@v2
with:
start: docker-compose -f ./docker-compose-cypress.yml up
wait-on: 'http://localhost:8080/dashboard'
wait-on: 'http://localhost:3000'
wait-on-timeout: 900
docker:

98
cypress/integration/app_gql_api_project_spec.js

@ -0,0 +1,98 @@
describe('GraphQL api project test', () => {
/*
before(() => {
cy.visit('http://localhost:3000', {retryOnNetworkFailure: true, timeout: 120000})
cy.waitForSpinners();
})
it('Sign Up / Sign In', () => {
// console.log('=====',cy.$$(cy.get('body')).find('.welcome-page').length)
cy.get('body').then(($body) => {
if ($body.find('.welcome-page').length > 0) {
// if (cy.get('body').find('.welcome-page').should('exist')) {
cy.wait(8000);
cy.get('body').trigger('mousemove');
cy.contains('Let\'s Begin').click();
cy.get('input[type="text"]').type('pranavc@gmail.com');
cy.get('input[type="password"]').type('Password123.');
cy.get('button:contains("SIGN UP")').click()
// cy.url().shou
} else {
cy.get('input[type="text"]').type('pranavc@gmail.com');
cy.get('input[type="password"]').type('Password123.');
cy.get('button:contains("SIGN IN")').click()
}
});
});
it('Create Project', () => {
cy.wait(1500);
cy.get('body').then($el => {
if ($el.find('.project-row').length) {
cy.get('.project-row').first().click();
} else {
cy.contains('New Project').trigger('onmouseover').trigger('mouseenter');
cy.get('.create-external-db-project').click()
cy.wait(1500);
cy.url().should('contain', '#/project')
cy.get('.database-field input').click().clear().type('sakila')
cy.contains('Test Database Connection').click()
cy.wait(1500);
cy.contains('Ok & Save Project').click()
}
cy.wait(5000);
cy.url().should('contain', '#/nc/')
})
});
it('Create Table', () => {
cy.get('.add-btn').click();
const name = 'Test' + Date.now();
cy.get('.nc-create-table-card .nc-table-name input[type="text"]').first().click().clear().type(name)
cy.get('.nc-create-table-card .nc-table-name-alias input[type="text"]').first().should('have.value', name.toLowerCase())
cy.wait(5000)
cy.get('.nc-create-table-card .nc-create-table-submit').first().click()
cy.get(`.project-tab:contains(${name})`).should('exist')
cy.url().should('contain', `?name=${name}&`)
});
it('Open and check country table', () => {
cy.contains('Country').click();
cy.get(`.project-tab:contains(Country)`).should('exist')
cy.url().should('contain', `?name=Country&`)
cy.get('td[data-col="Country => City"] div').first().click()
cy.get('td[data-col="Country => City"] div .mdi-arrow-expand').first().click()
cy.get(":contains(Link to 'City')").should('exist')
cy.get(":contains(Link to 'City'):visible").click()
});
it('Open and check actor table for m2m', () => {
cy.contains('Actor').click();
cy.get(`.project-tab:contains(Actor)`).should('exist')
cy.url().should('contain', `?name=Actor&`)
cy.get('td[data-col="Actor <=> Film"] div').first().click()
cy.get('td[data-col="Actor <=> Film"] div .mdi-arrow-expand').first().click()
//
// cy.get(":contains(Link to 'City')").should('exist')
//
// cy.get(":contains(Link to 'City'):visible").click()
});
*/
})

5
cypress/integration/app_rest_api_project_spec.js

@ -1,6 +1,6 @@
describe('Rest api project test', () => {
before(() => {
/* before(() => {
cy.visit('http://localhost:3000', {retryOnNetworkFailure: true, timeout: 120000})
cy.waitForSpinners();
})
@ -79,6 +79,7 @@ describe('Rest api project test', () => {
cy.get(":contains(Link to 'City'):visible").first().click()
});
//
it('Open and check actor table for m2m', () => {
cy.contains('Actor').first().click({force: true});
@ -97,6 +98,6 @@ describe('Rest api project test', () => {
cy.contains('Save Row').should('exist');
cy.contains('Save Row').should('exist');
});
});*/
})

21
cypress/integration/graphql/create_table_spec.js

@ -0,0 +1,21 @@
describe('Rest api project test', () => {
before(() => {
cy.visit('http://localhost:3000', {retryOnNetworkFailure: true, timeout: 120000})
cy.waitForSpinners();
cy.openOrCreateGqlProject();
})
it('Create Table', () => {
cy.get('.add-btn').click();
const name = 'Test' + Date.now();
cy.get('.nc-create-table-card .nc-table-name input[type="text"]').first().click().clear().type(name)
cy.get('.nc-create-table-card .nc-table-name-alias input[type="text"]').first().should('have.value', name.toLowerCase())
cy.wait(5000)
cy.get('.nc-create-table-card .nc-create-table-submit').first().click()
cy.get(`.project-tab:contains(${name})`).should('exist')
cy.url().should('contain', `?name=${name}&`)
});
})

27
cypress/integration/graphql/open_existing_table_spec.js

@ -0,0 +1,27 @@
describe('GraphQL api - Existing table', () => {
before(() => {
cy.visit('http://localhost:3000', {retryOnNetworkFailure: true, timeout: 120000})
cy.waitForSpinners();
cy.openOrCreateGqlProject();
})
it('Open Country table', () => {
cy.get('.nc-project-tree :contains(Tables)', {timeout: 10000})
.first().click()
.contains('Country', {timeout: 6000}).first().click({force: true});
cy.get(`.project-tab:contains(Country):visible`).should('exist')
cy.url().should('contain', `?name=Country&`)
cy.get('td[data-col="Country => City"] div:visible', {timeout: 6000}).first().click()
cy.get('td[data-col="Country => City"] div .mdi-arrow-expand:visible').first().click()
cy.get(":contains(Link to 'City'):visible").should('exist')
cy.get(":contains(Link to 'City'):visible").first().click()
});
})

34
cypress/integration/graphql/open_existing_table_with_m2m_spec.js

@ -0,0 +1,34 @@
describe('GraphQL api - Existing table with M2M', () => {
before(() => {
cy.visit('http://localhost:3000', {retryOnNetworkFailure: true, timeout: 120000})
cy.waitForSpinners();
cy.openOrCreateGqlProject();
})
it('Open Actor table', () => {
cy.get('.nc-project-tree :contains(Tables)', {timeout: 10000})
.first().click()
.contains('Actor', {timeout: 6000}).first().click({force: true});
cy.get(`.project-tab:contains(Actor)`).should('exist')
cy.url().should('contain', `?name=Actor&`)
cy.get('td[data-col="Actor <=> Film"] div').first().click({force: true})
cy.get('td[data-col="Actor <=> Film"] div .mdi-arrow-expand').first().click({force: true})
//
// cy.get(":contains(Link to 'City')").should('exist')
//
// cy.get(":contains(Link to 'City'):visible").click()
cy.get('.child-card:visible').should('exist').first().click()
cy.contains('Save Row').should('exist');
cy.contains('Save Row').should('exist');
});
})

21
cypress/integration/rest/create_table_spec.js

@ -0,0 +1,21 @@
describe('Rest api - New table', () => {
before(() => {
cy.visit('http://localhost:3000', {retryOnNetworkFailure: true, timeout: 120000})
cy.waitForSpinners();
cy.openOrCreateRestProject();
})
it('Create Table', () => {
cy.get('.add-btn').click();
const name = 'Test' + Date.now();
cy.get('.nc-create-table-card .nc-table-name input[type="text"]').first().click().clear().type(name)
cy.get('.nc-create-table-card .nc-table-name-alias input[type="text"]').first().should('have.value', name.toLowerCase())
cy.wait(5000)
cy.get('.nc-create-table-card .nc-create-table-submit').first().click()
cy.get(`.project-tab:contains(${name})`).should('exist')
cy.url().should('contain', `?name=${name}&`)
});
})

27
cypress/integration/rest/open_existing_table_spec.js

@ -0,0 +1,27 @@
describe('Rest api - Existing table', () => {
before(() => {
cy.visit('http://localhost:3000', {retryOnNetworkFailure: true, timeout: 120000})
cy.waitForSpinners();
cy.openOrCreateRestProject();
})
it('Open Country table', () => {
cy.get('.nc-project-tree :contains(Tables)', {timeout: 10000})
.first().click()
.contains('Country', {timeout: 6000}).first().click({force: true});
cy.get(`.project-tab:contains(Country):visible`).should('exist')
cy.url().should('contain', `?name=Country&`)
cy.get('td[data-col="Country => City"] div:visible', {timeout: 6000}).first().click()
cy.get('td[data-col="Country => City"] div .mdi-arrow-expand:visible').first().click()
cy.get(":contains(Link to 'City'):visible").should('exist')
cy.get(":contains(Link to 'City'):visible").first().click()
});
})

34
cypress/integration/rest/open_existing_table_with_m2m_spec.js

@ -0,0 +1,34 @@
describe('Rest api - Existing table with M2M', () => {
before(() => {
cy.visit('http://localhost:3000', {retryOnNetworkFailure: true, timeout: 120000})
cy.waitForSpinners();
cy.openOrCreateRestProject();
})
it('Open Actor table', () => {
cy.get('.nc-project-tree :contains(Tables)', {timeout: 10000})
.first().click()
.contains('Actor', {timeout: 6000}).first().click({force: true});
cy.get(`.project-tab:contains(Actor)`).should('exist')
cy.url().should('contain', `?name=Actor&`)
cy.get('td[data-col="Actor <=> Film"] div').first().click({force: true})
cy.get('td[data-col="Actor <=> Film"] div .mdi-arrow-expand').first().click({force: true})
//
// cy.get(":contains(Link to 'City')").should('exist')
//
// cy.get(":contains(Link to 'City'):visible").click()
cy.get('.child-card:visible').should('exist').first().click()
cy.contains('Save Row').should('exist');
cy.contains('Save Row').should('exist');
});
})

84
cypress/support/commands.js

@ -23,6 +23,88 @@
//
// -- This will overwrite an existing command --
// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
// for waiting until page load
Cypress.Commands.add('waitForSpinners', () => {
cy.get('#nuxt-loading', { timeout: 10_000 }).should('have.length', 0)
cy.get('#nuxt-loading', {timeout: 10_000}).should('have.length', 0)
})
// for opening/creating a rest project
Cypress.Commands.add('openOrCreateRestProject', () => {
// signin/signup
cy.get('body').then(($body) => {
// handle initial load
if ($body.find('.welcome-page').length > 0) {
cy.wait(8000);
cy.get('body').trigger('mousemove');
cy.contains('Let\'s Begin').click();
cy.get('input[type="text"]').type('pranavc@gmail.com');
cy.get('input[type="password"]').type('Password123.');
cy.get('button:contains("SIGN UP")').click()
// handle signin
} else {
cy.get('input[type="text"]').type('pranavc@gmail.com');
cy.get('input[type="password"]').type('Password123.');
cy.get('button:contains("SIGN IN")').click()
}
});
cy.wait(2000);
cy.get('body').then($body => {
// if project exist open
if ($body.find('.nc-rest-project-row').length) {
cy.get('.nc-rest-project-row').first().click()
// create new project
} else {
cy.contains('New Project').trigger('onmouseover').trigger('mouseenter');
cy.get('.create-external-db-project').click()
cy.url({timeout: 6000}).should('contain', '#/project')
cy.get('.database-field input').click().clear().type('sakila')
cy.contains('Test Database Connection').click()
cy.contains('Ok & Save Project', {timeout: 3000}).click()
}
})
cy.url({timeout: 20000}).should('contain', '#/nc/')
})
Cypress.Commands.add('openOrCreateGqlProject', () => {
// signin/signup
cy.get('body').then(($body) => {
// handle initial load
if ($body.find('.welcome-page').length > 0) {
cy.wait(8000);
cy.get('body').trigger('mousemove');
cy.contains('Let\'s Begin').click();
cy.get('input[type="text"]').type('pranavc@gmail.com');
cy.get('input[type="password"]').type('Password123.');
cy.get('button:contains("SIGN UP")').click()
// handle signin
} else {
cy.get('input[type="text"]').type('pranavc@gmail.com');
cy.get('input[type="password"]').type('Password123.');
cy.get('button:contains("SIGN IN")').click()
}
});
cy.wait(2000);
cy.get('body').then($body => {
// if project exist open
if ($body.find('.nc-graphql-project-row').length) {
cy.get('.nc-graphql-project-row').first().click()
// create new project
} else {
cy.contains('New Project').trigger('onmouseover').trigger('mouseenter');
cy.get('.create-external-db-project').click()
cy.url({timeout: 6000}).should('contain', '#/project')
cy.contains('GRAPHQL APIs').closest('label').click()
cy.get('.database-field input').click().clear().type('sakila')
cy.contains('Test Database Connection').click()
cy.contains('Ok & Save Project', {timeout: 3000}).click()
}
})
cy.url({timeout: 20000}).should('contain', '#/nc/')
})

4
docker-compose-cypress.yml

@ -19,7 +19,7 @@ services:
- -c
- |
echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
cd /home/app/ && npm i && npm run run
cd /home/app/ && rm package-lock.json && npm i && npm run run
xc-cypress-nc-gui:
network_mode: host
image: node:12.22.1-slim
@ -34,4 +34,4 @@ services:
- -c
- |
echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
cd /home/app/ && npm i && npm run dev
cd /home/app/ && rm package-lock.json && npm i && npm run dev

6
packages/nc-gui/components/ProjectTreeView.vue

@ -8,7 +8,7 @@
mini-variant-width="50"
:mini-variant.sync="mini"
mini
class="pl-2"
class="pl-2 nc-nav-drawer"
style="min-width: 100%; height: 100%"
>
<div class="h-100 d-flex flex-column">
@ -45,7 +45,7 @@
<v-treeview
v-else-if="isTreeView"
v-model="tree"
class="mt-5 project-tree"
class="mt-5 project-tree nc-project-tree"
dense
:open.sync="open"
:active.sync="active"
@ -109,7 +109,7 @@
</template>
</v-treeview>
<v-container v-else fluid class="px-1">
<v-list dense expand>
<v-list dense expand class="nc-project-tree nc-single-env-project-tree">
<template v-for="item in listViewArr">
<!-- v-if="item.children && item.children.length"-->
<v-list-group

14882
packages/nc-gui/package-lock.json generated

File diff suppressed because it is too large Load Diff

6
packages/nc-gui/pages/projects/index.vue

@ -223,7 +223,11 @@
style="cursor: pointer"
>
<template #item="props">
<tr class="project-row" @click="projectRouteHandler(props.item)">
<tr
class="project-row"
:class="`nc-${props.item.projectType}-project-row`"
@click="projectRouteHandler(props.item)"
>
<td data-v-step="2">
<v-icon
x-small

18
packages/nocodb/package-lock.json generated

@ -2973,16 +2973,6 @@
"integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
"dev": true
},
"bindings": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz",
"integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==",
"dev": true,
"optional": true,
"requires": {
"file-uri-to-path": "1.0.0"
}
},
"bl": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
@ -7767,13 +7757,6 @@
"integrity": "sha512-rM0UO7Qm9K7TWTtA6AShI/t7H5BPjDeGVDaNyg9BjHAj3PysKy7+8C8D137R88jnR3rFJZQB/tFgydl5sN5m7g==",
"dev": true
},
"file-uri-to-path": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz",
"integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==",
"dev": true,
"optional": true
},
"filelist": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.2.tgz",
@ -18805,7 +18788,6 @@
"dev": true,
"optional": true,
"requires": {
"bindings": "^1.5.0",
"nan": "^2.12.1"
}
},

Loading…
Cancel
Save