如何通过ssh隧道连接mysql和cypress?

2022-03-13 00:00:00 node.js ssh-tunnel mysql cypress

目前Cypress支持不使用ssh的MySQL连接,如下面的链接所示

https://docs.cypress.io/api/commands/task#Allows-a-single-argument-only

但是我正在尝试通过ssh隧道将Cypress连接到MySQL。 我正在使用NPM包mysql-ssh建立连接。

我可以使用node.js直接实现这一点,但我在通过Cypress实现时遇到了问题。以下是我在node.js中尝试的代码片段。

const mysqlssh = require('mysql-ssh');
const fs = require('fs');

mysqlssh.connect(
    {
        host: 'x.x.x.x',
        user: 'xyz',
        privateKey: fs.readFileSync('filePath')  //this is the ssh filePath
    },
    {
        host: 'HOST_NAME',
        user: 'USER_NAME',
        password: 'xxxx',
        database: 'DB_NAME'
    }
)
.then(client => {
    client.query('select * from TABLE_NAME',  function (err, results, fields) {
        if (err)
        {
            console.log(err)
        }
        console.log(results);
        mysqlssh.close()
    })
})
.catch(err => {
    console.log(err)
})
我希望通过cypress/plugins/index.js文件或直接在cypress/integration中执行此操作。有什么简单的方法可以做到这一点吗?


解决方案

我已找到解决方案。以下是我的cypress/plugins/index.js文件代码:

const dotenvPlugin = require('cypress-dotenv');
const mysqlssh = require('mysql-ssh');
const fs = require('fs');

module.exports = (on, config) => {
  //  `config` is the resolved Cypress config
    config = dotenvPlugin(config);

    on('task', {
        executeSql (sql, ...args) {
            return new Promise(async (resolve, reject) => {
                try {
                    let connection = await mysqlssh.connect(  {
                            host: process.env.SSH_HOST,
                            user: process.env.SSH_USER,
                            privateKey: fs.readFileSync(process.env.HOME + '/.ssh/id_rsa_old')
                        },
                        {
                            host: process.env.MYSQL_HOST,
                            user: process.env.MYSQL_USER,
                            password: process.env.MYSQL_PASSWORD,
                            database: process.env.MYSQL_DB
                        });
                    let result = await connection.promise().query(sql, args);
                    mysqlssh.close();
                    resolve(result[0][0]); 
                } catch (err) {
                    reject(err);
                }
            });
        }
    })

    return config
}
因此,必须在此文件中建立此连接。b/c cypress不与主机提供的节点进程通信。因此,我们需要使用Cypress任务来运行节点代码。请参阅此处的文档-https://docs.cypress.io/api/commands/task#Examples

在一个测试文件示例中,我是这样使用它的:

describe('Db Test',  () => {
    it('Query Test', () => {
        cy.task('executeSql', 'SELECT count(id) as cnt FROM table_name').then(result => {
            expect(result.cnt, 'Does not equal to 8').to.equal(2000);
        })
    })
})

P.S.其他cypress-dotenv包仅用于从.env文件加载环境变量。

相关文章