mirror of
https://github.com/DeNNiiInc/dbgate.git
synced 2026-04-24 03:45:59 +00:00
next e2e tests
This commit is contained in:
1
.github/workflows/run-tests-pro.yaml
vendored
1
.github/workflows/run-tests-pro.yaml
vendored
@@ -62,6 +62,7 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
mkdir screenshots
|
mkdir screenshots
|
||||||
cp ../dbgate-merged/e2e-tests/cypress/screenshots/**/*.png screenshots/
|
cp ../dbgate-merged/e2e-tests/cypress/screenshots/**/*.png screenshots/
|
||||||
|
cp ../dbgate-merged/e2e-tests/cypress/screenshots/*.png screenshots/
|
||||||
- name: Upload E2E screenshots
|
- name: Upload E2E screenshots
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
|
|||||||
@@ -1,12 +1,47 @@
|
|||||||
|
Cypress.on('uncaught:exception', (err, runnable) => {
|
||||||
|
// if the error message matches the one about WorkerGlobalScope importScripts
|
||||||
|
if (err.message.includes("Failed to execute 'importScripts' on 'WorkerGlobalScope'")) {
|
||||||
|
// return false to let Cypress know we intentionally want to ignore this error
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// otherwise let Cypress throw the error
|
||||||
|
});
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.visit('http://localhost:3000');
|
cy.visit('http://localhost:3000');
|
||||||
cy.viewport(1250, 900);
|
cy.viewport(1250, 900);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Data browser data', () => {
|
describe('Data browser data', () => {
|
||||||
|
it('Export to data archive', () => {
|
||||||
|
cy.contains('MySql-connection').click();
|
||||||
|
// cy.contains('MyChinook').click();
|
||||||
|
// cy.contains('Album').click();
|
||||||
|
cy.contains('MyChinook').rightclick();
|
||||||
|
cy.contains('Export').click();
|
||||||
|
cy.wait(1000);
|
||||||
|
cy.testid('SourceTargetConfig_buttonCurrentArchive_target').click();
|
||||||
|
cy.testid('FormTablesSelect_buttonAll_tables').click();
|
||||||
|
// cy.wait(4000);
|
||||||
|
// cy.contains('All tables').click();
|
||||||
|
cy.contains('Run').click();
|
||||||
|
cy.contains('Finished job script');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Data archive editor', () => {
|
||||||
|
cy.testid('WidgetIconPanel_archive').click();
|
||||||
|
cy.contains('Album').click();
|
||||||
|
cy.testid('DataGrid_itemFilters').click();
|
||||||
|
cy.contains('Let There Be Rock').click();
|
||||||
|
cy.contains('Out Of Exile').click({ shiftKey: true });
|
||||||
|
cy.contains('Change text case').click();
|
||||||
|
cy.contains('AUDIOSLAVE');
|
||||||
|
cy.screenshot('freetable');
|
||||||
|
});
|
||||||
|
|
||||||
it('Load table data', () => {
|
it('Load table data', () => {
|
||||||
cy.contains('MySql-connection').click();
|
cy.contains('MySql-connection').click();
|
||||||
cy.contains('Chinook').click();
|
cy.contains('MyChinook').click();
|
||||||
cy.contains('Album').click();
|
cy.contains('Album').click();
|
||||||
cy.contains('Let There Be Rock').click();
|
cy.contains('Let There Be Rock').click();
|
||||||
cy.contains('Rows: 347');
|
cy.contains('Rows: 347');
|
||||||
@@ -16,7 +51,7 @@ describe('Data browser data', () => {
|
|||||||
|
|
||||||
it('Filter model', () => {
|
it('Filter model', () => {
|
||||||
cy.contains('MySql-connection').click();
|
cy.contains('MySql-connection').click();
|
||||||
cy.contains('Chinook').click();
|
cy.contains('MyChinook').click();
|
||||||
cy.testid('SqlObjectList_search').clear().type('album');
|
cy.testid('SqlObjectList_search').clear().type('album');
|
||||||
cy.contains('Tables (1/11)');
|
cy.contains('Tables (1/11)');
|
||||||
cy.contains('347 rows, InnoDB');
|
cy.contains('347 rows, InnoDB');
|
||||||
@@ -31,7 +66,7 @@ describe('Data browser data', () => {
|
|||||||
|
|
||||||
it('Show raw data', () => {
|
it('Show raw data', () => {
|
||||||
cy.contains('MySql-connection').click();
|
cy.contains('MySql-connection').click();
|
||||||
cy.contains('Chinook').click();
|
cy.contains('MyChinook').click();
|
||||||
cy.contains('Album').rightclick();
|
cy.contains('Album').rightclick();
|
||||||
cy.contains('Open raw data').click();
|
cy.contains('Open raw data').click();
|
||||||
cy.contains('Let There Be Rock').click();
|
cy.contains('Let There Be Rock').click();
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
const path = require('path');
|
const path = require('path');
|
||||||
|
const fs = require('fs');
|
||||||
|
|
||||||
const dbgateApi = require('dbgate-api');
|
const dbgateApi = require('dbgate-api');
|
||||||
dbgateApi.initializeApiEnvironment();
|
dbgateApi.initializeApiEnvironment();
|
||||||
const dbgatePluginMysql = require('dbgate-plugin-mysql');
|
const dbgatePluginMysql = require('dbgate-plugin-mysql');
|
||||||
@@ -78,12 +80,100 @@ async function initPostgresDatabase(dbname, inputFile) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function initMongoDatabase(dbname, inputDirectory) {
|
||||||
|
await dbgateApi.executeQuery({
|
||||||
|
connection: {
|
||||||
|
server: process.env.SERVER_mongo,
|
||||||
|
user: process.env.USER_mongo,
|
||||||
|
password: process.env.PASSWORD_mongo,
|
||||||
|
port: process.env.PORT_mongo,
|
||||||
|
database: dbname,
|
||||||
|
engine: 'mongo@dbgate-plugin-mongo',
|
||||||
|
},
|
||||||
|
sql: 'db.dropDatabase()',
|
||||||
|
});
|
||||||
|
|
||||||
|
for (const file of fs.readdirSync(inputDirectory)) {
|
||||||
|
const pureName = path.parse(file).name;
|
||||||
|
const src = await dbgateApi.jsonLinesReader({ fileName: path.join(inputDirectory, file) });
|
||||||
|
const dst = await dbgateApi.tableWriter({
|
||||||
|
connection: {
|
||||||
|
server: process.env.SERVER_mongo,
|
||||||
|
user: process.env.USER_mongo,
|
||||||
|
password: process.env.PASSWORD_mongo,
|
||||||
|
port: process.env.PORT_mongo,
|
||||||
|
database: dbname,
|
||||||
|
engine: 'mongo@dbgate-plugin-mongo',
|
||||||
|
},
|
||||||
|
pureName,
|
||||||
|
createIfNotExists: true,
|
||||||
|
});
|
||||||
|
await dbgateApi.copyStream(src, dst);
|
||||||
|
}
|
||||||
|
|
||||||
|
// await dbgateApi.importDatabase({
|
||||||
|
// connection: {
|
||||||
|
// server: process.env.SERVER_postgres,
|
||||||
|
// user: process.env.USER_postgres,
|
||||||
|
// password: process.env.PASSWORD_postgres,
|
||||||
|
// port: process.env.PORT_postgres,
|
||||||
|
// database: dbname,
|
||||||
|
// engine: 'postgres@dbgate-plugin-postgres',
|
||||||
|
// },
|
||||||
|
// inputFile,
|
||||||
|
// });
|
||||||
|
}
|
||||||
|
|
||||||
|
async function initRedisDatabase(inputDirectory) {
|
||||||
|
await dbgateApi.executeQuery({
|
||||||
|
connection: {
|
||||||
|
server: process.env.SERVER_redis,
|
||||||
|
user: process.env.USER_redis,
|
||||||
|
password: process.env.PASSWORD_redis,
|
||||||
|
port: process.env.PORT_redis,
|
||||||
|
engine: 'redis@dbgate-plugin-redis',
|
||||||
|
},
|
||||||
|
sql: 'FLUSHALL',
|
||||||
|
});
|
||||||
|
|
||||||
|
for (const file of fs.readdirSync(inputDirectory)) {
|
||||||
|
await dbgateApi.executeQuery({
|
||||||
|
connection: {
|
||||||
|
server: process.env.SERVER_redis,
|
||||||
|
user: process.env.USER_redis,
|
||||||
|
password: process.env.PASSWORD_redis,
|
||||||
|
port: process.env.PORT_redis,
|
||||||
|
engine: 'redis@dbgate-plugin-redis',
|
||||||
|
database: 0,
|
||||||
|
},
|
||||||
|
sqlFile: path.join(inputDirectory, file),
|
||||||
|
// logScriptItems: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// await dbgateApi.importDatabase({
|
||||||
|
// connection: {
|
||||||
|
// server: process.env.SERVER_postgres,
|
||||||
|
// user: process.env.USER_postgres,
|
||||||
|
// password: process.env.PASSWORD_postgres,
|
||||||
|
// port: process.env.PORT_postgres,
|
||||||
|
// database: dbname,
|
||||||
|
// engine: 'postgres@dbgate-plugin-postgres',
|
||||||
|
// },
|
||||||
|
// inputFile,
|
||||||
|
// });
|
||||||
|
}
|
||||||
|
|
||||||
async function run() {
|
async function run() {
|
||||||
await initMySqlDatabase('MyChinook', path.resolve(path.join(__dirname, '../data/chinook-mysql.sql')));
|
await initMySqlDatabase('MyChinook', path.resolve(path.join(__dirname, '../data/chinook-mysql.sql')));
|
||||||
// await initMySqlDatabase('Northwind', path.resolve(path.join(__dirname, '../data/northwind-mysql.sql')));
|
// await initMySqlDatabase('Northwind', path.resolve(path.join(__dirname, '../data/northwind-mysql.sql')));
|
||||||
// await initMySqlDatabase('Sakila', path.resolve(path.join(__dirname, '../data/sakila-mysql.sql')));
|
// await initMySqlDatabase('Sakila', path.resolve(path.join(__dirname, '../data/sakila-mysql.sql')));
|
||||||
|
|
||||||
await initPostgresDatabase('PgChinook', path.resolve(path.join(__dirname, '../data/chinook-postgres.sql')));
|
await initPostgresDatabase('PgChinook', path.resolve(path.join(__dirname, '../data/chinook-postgres.sql')));
|
||||||
|
|
||||||
|
await initMongoDatabase('MgChinook', path.resolve(path.join(__dirname, '../data/mongo')));
|
||||||
|
|
||||||
|
await initRedisDatabase(path.resolve(path.join(__dirname, '../data/redis')));
|
||||||
}
|
}
|
||||||
|
|
||||||
dbgateApi.runScript(run);
|
dbgateApi.runScript(run);
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
"start:add-connection": "cd .. && node packer/build/bundle.js --listen-api --run-e2e-tests",
|
"start:add-connection": "cd .. && node packer/build/bundle.js --listen-api --run-e2e-tests",
|
||||||
"start:portal": "cd .. && env-cmd -f e2e-tests/env/portal/.env node e2e-tests/init/portal.js && env-cmd -f e2e-tests/env/portal/.env node packer/build/bundle.js --listen-api --run-e2e-tests",
|
"start:portal": "cd .. && env-cmd -f e2e-tests/env/portal/.env node e2e-tests/init/portal.js && env-cmd -f e2e-tests/env/portal/.env node packer/build/bundle.js --listen-api --run-e2e-tests",
|
||||||
"start:oauth": "cd .. && env-cmd -f e2e-tests/env/oauth/.env node packer/build/bundle.js --listen-api --run-e2e-tests",
|
"start:oauth": "cd .. && env-cmd -f e2e-tests/env/oauth/.env node packer/build/bundle.js --listen-api --run-e2e-tests",
|
||||||
"start:browse-data": "cd .. && env-cmd -f e2e-tests/env/portal/.env node e2e-tests/init/browse-data.js && env-cmd -f e2e-tests/env/browse-data/.env node packer/build/bundle.js --listen-api --run-e2e-tests",
|
"start:browse-data": "cd .. && env-cmd -f e2e-tests/env/browse-data/.env node e2e-tests/init/browse-data.js && env-cmd -f e2e-tests/env/browse-data/.env node packer/build/bundle.js --listen-api --run-e2e-tests",
|
||||||
|
|
||||||
"test": "start-server-and-test start:add-connection http://localhost:3000 cy:run:add-connection && start-server-and-test start:portal http://localhost:3000 cy:run:portal && start-server-and-test start:oauth http://localhost:3000 cy:run:oauth && start-server-and-test start:browse-data http://localhost:3000 cy:run:browse-data",
|
"test": "start-server-and-test start:add-connection http://localhost:3000 cy:run:add-connection && start-server-and-test start:portal http://localhost:3000 cy:run:portal && start-server-and-test start:oauth http://localhost:3000 cy:run:oauth && start-server-and-test start:browse-data http://localhost:3000 cy:run:browse-data",
|
||||||
"test:ci": "yarn test"
|
"test:ci": "yarn test"
|
||||||
|
|||||||
@@ -28,9 +28,9 @@ function getPassArgs() {
|
|||||||
if (listenApiChild) {
|
if (listenApiChild) {
|
||||||
res.push('listen-api-child');
|
res.push('listen-api-child');
|
||||||
}
|
}
|
||||||
// if (runE2eTests) {
|
if (runE2eTests) {
|
||||||
// res.push('--run-e2e-tests');
|
res.push('--run-e2e-tests');
|
||||||
// }
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -172,7 +172,13 @@
|
|||||||
>
|
>
|
||||||
<div class="left" slot="1">
|
<div class="left" slot="1">
|
||||||
<WidgetColumnBar>
|
<WidgetColumnBar>
|
||||||
<WidgetColumnBarItem title="Columns" name="columns" height="45%" skip={isFormView}>
|
<WidgetColumnBarItem
|
||||||
|
title="Columns"
|
||||||
|
name="columns"
|
||||||
|
height="45%"
|
||||||
|
skip={isFormView}
|
||||||
|
data-testid="DataGrid_itemColumns"
|
||||||
|
>
|
||||||
<ColumnManager {...$$props} {managerSize} {isJsonView} {isDynamicStructure} bind:this={domColumnManager} />
|
<ColumnManager {...$$props} {managerSize} {isJsonView} {isDynamicStructure} bind:this={domColumnManager} />
|
||||||
</WidgetColumnBarItem>
|
</WidgetColumnBarItem>
|
||||||
|
|
||||||
@@ -182,6 +188,7 @@
|
|||||||
height={showReferences && display?.hasReferences && !isFormView ? '15%' : '30%'}
|
height={showReferences && display?.hasReferences && !isFormView ? '15%' : '30%'}
|
||||||
skip={!display?.filterable}
|
skip={!display?.filterable}
|
||||||
collapsed={isDetailView}
|
collapsed={isDetailView}
|
||||||
|
data-testid="DataGrid_itemFilters"
|
||||||
>
|
>
|
||||||
<FormViewFilters
|
<FormViewFilters
|
||||||
{...$$props}
|
{...$$props}
|
||||||
@@ -199,11 +206,18 @@
|
|||||||
height="30%"
|
height="30%"
|
||||||
collapsed={isDetailView}
|
collapsed={isDetailView}
|
||||||
skip={!(showReferences && display?.hasReferences)}
|
skip={!(showReferences && display?.hasReferences)}
|
||||||
|
data-testid="DataGrid_itemReferences"
|
||||||
>
|
>
|
||||||
<ReferenceManager {...$$props} {managerSize} />
|
<ReferenceManager {...$$props} {managerSize} />
|
||||||
</WidgetColumnBarItem>
|
</WidgetColumnBarItem>
|
||||||
|
|
||||||
<WidgetColumnBarItem title="Macros" name="macros" skip={!showMacros} collapsed={!expandMacros}>
|
<WidgetColumnBarItem
|
||||||
|
title="Macros"
|
||||||
|
name="macros"
|
||||||
|
skip={!showMacros}
|
||||||
|
collapsed={!expandMacros}
|
||||||
|
data-testid="DataGrid_itemMacros"
|
||||||
|
>
|
||||||
<MacroManager {...$$props} {managerSize} />
|
<MacroManager {...$$props} {managerSize} />
|
||||||
</WidgetColumnBarItem>
|
</WidgetColumnBarItem>
|
||||||
</WidgetColumnBar>
|
</WidgetColumnBar>
|
||||||
|
|||||||
@@ -42,6 +42,7 @@
|
|||||||
<FormStyledButton
|
<FormStyledButton
|
||||||
type="button"
|
type="button"
|
||||||
value={`All ${field}`}
|
value={`All ${field}`}
|
||||||
|
data-testid={`FormTablesSelect_buttonAll_${field}`}
|
||||||
on:click={() =>
|
on:click={() =>
|
||||||
setFieldValue(
|
setFieldValue(
|
||||||
name,
|
name,
|
||||||
|
|||||||
@@ -84,6 +84,9 @@
|
|||||||
{/if}
|
{/if}
|
||||||
<FormStyledButton
|
<FormStyledButton
|
||||||
value="Current archive"
|
value="Current archive"
|
||||||
|
data-testid={direction == 'source'
|
||||||
|
? 'SourceTargetConfig_buttonCurrentArchive_source'
|
||||||
|
: 'SourceTargetConfig_buttonCurrentArchive_target'}
|
||||||
on:click={() => {
|
on:click={() => {
|
||||||
values.update(x => ({
|
values.update(x => ({
|
||||||
...x,
|
...x,
|
||||||
|
|||||||
@@ -67,7 +67,11 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if !skip}
|
{#if !skip}
|
||||||
<WidgetTitle clickable={collapsible} on:click={collapsible ? () => (visible = !visible) : null}>{title}</WidgetTitle>
|
<WidgetTitle
|
||||||
|
clickable={collapsible}
|
||||||
|
on:click={collapsible ? () => (visible = !visible) : null}
|
||||||
|
data-testid={$$props['data-testid']}>{title}</WidgetTitle
|
||||||
|
>
|
||||||
|
|
||||||
{#if visible}
|
{#if visible}
|
||||||
<div class="wrapper" style={$dynamicProps.splitterVisible ? `height:${size}px` : 'flex: 1 1 0'}>
|
<div class="wrapper" style={$dynamicProps.splitterVisible ? `height:${size}px` : 'flex: 1 1 0'}>
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
export let clickable = false;
|
export let clickable = false;
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div on:click class:clickable>
|
<div on:click class:clickable {...$$restProps}>
|
||||||
<slot />
|
<slot />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -114,6 +114,15 @@ const driver = {
|
|||||||
},
|
},
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
async query(dbhan, sql) {
|
async query(dbhan, sql) {
|
||||||
|
const parts = splitCommandLine(sql);
|
||||||
|
|
||||||
|
if (parts.length >= 1) {
|
||||||
|
const command = parts[0].toLowerCase();
|
||||||
|
const args = parts.slice(1);
|
||||||
|
await dbhan.client.call(command, ...args);
|
||||||
|
}
|
||||||
|
|
||||||
|
// redis queries don't return rows
|
||||||
return {
|
return {
|
||||||
rows: [],
|
rows: [],
|
||||||
columns: [],
|
columns: [],
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
mkdir screenshots
|
mkdir screenshots
|
||||||
cp ../dbgate-merged/e2e-tests/cypress/screenshots/**/*.png screenshots/
|
cp ../dbgate-merged/e2e-tests/cypress/screenshots/**/*.png screenshots/
|
||||||
|
cp ../dbgate-merged/e2e-tests/cypress/screenshots/*.png screenshots/
|
||||||
|
|
||||||
- name: Upload E2E screenshots
|
- name: Upload E2E screenshots
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
|
|||||||
Reference in New Issue
Block a user