WIP: Move test to cypress.io
This is mostly just a PoC to see if our CI infrastructure is able to run cypress.io tests. Changing language currently triggers a "500 Parse Error" in cypress, which needs to be fixed in Cockpit.
This commit is contained in:
parent
5d73df67ee
commit
caf96475e2
7 changed files with 134 additions and 65 deletions
54
cypress/integration/application.js
Normal file
54
cypress/integration/application.js
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
// Use this for skipping the login page, i. e. all tests which do not test the login page itself
|
||||
const visit_opts = { auth: { username: 'admin', password: 'foobar' } };
|
||||
|
||||
describe('Application', () => {
|
||||
beforeEach('start VM', function () {
|
||||
cy.task('startVM').then(url => Cypress.config('baseUrl', url));
|
||||
|
||||
// Programmatically enable the "Reuse my password for privileged tasks" option
|
||||
cy.server({
|
||||
onAnyRequest: function (route, proxy) {
|
||||
proxy.xhr.setRequestHeader('X-Authorize', 'password');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
afterEach('stop VM', function() {
|
||||
cy.task('stopVM');
|
||||
});
|
||||
|
||||
it('basic functionality', function () {
|
||||
// cypress doesn't handle frames, so go to specific frame
|
||||
cy.visit('/cockpit/@localhost/starter-kit/index.html', visit_opts)
|
||||
// verify expected heading
|
||||
cy.get('.container-fluid h2').should('contain', 'Starter Kit');
|
||||
// verify expected host name
|
||||
cy.task('runVM', 'cat /etc/hostname').then(out => {
|
||||
cy.get('.container-fluid p').should('contain', 'Running on ' + out.trim());
|
||||
});
|
||||
});
|
||||
|
||||
it('test with German translations', function() {
|
||||
cy.visit('/', visit_opts);
|
||||
|
||||
// change language in menu
|
||||
cy.get('#content-user-name').click();
|
||||
cy.get('.display-language-menu a').click();
|
||||
cy.get('#display-language select').select('de-de');
|
||||
|
||||
// HACK: language switching in Chrome not working in current session (Cockpit issue #8160)
|
||||
cy.on('uncaught:exception', (err, runnable) => {
|
||||
cy.log("Uncaught exception:", err);
|
||||
return false;
|
||||
});
|
||||
|
||||
// menu label (from manifest) should be translated
|
||||
cy.get('#display-language-select-button').click();
|
||||
cy.get("#host-apps a[href='/starter-kit']").should('contain', 'Bausatz');
|
||||
|
||||
// page label (from js) should be translated
|
||||
cy.visit('/cockpit/@localhost/starter-kit/index.html');
|
||||
cy.get('.container-fluid p').should('contain', 'Läuft auf');
|
||||
});
|
||||
|
||||
})
|
||||
69
cypress/plugins/index.js
Normal file
69
cypress/plugins/index.js
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
const child_process = require("child_process");
|
||||
|
||||
var vm_proc, ssh_args, cockpit_url;
|
||||
|
||||
// poor man's polling implementation
|
||||
function waitpid(pid) {
|
||||
return new Promise((resolve, reject) => {
|
||||
function check() {
|
||||
try {
|
||||
process.kill(pid);
|
||||
// succeeds → process still exists, poll again
|
||||
setTimeout(check, 50);
|
||||
} catch(e) {
|
||||
// ESRCH → process is gone
|
||||
if (e.code == "ESRCH")
|
||||
resolve(null);
|
||||
else
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
check();
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = (on, config) => {
|
||||
on("task", {
|
||||
startVM: image => {
|
||||
if (!image)
|
||||
image = process.env.TEST_OS || "fedora-29";
|
||||
// already running? happens when cypress restarts the test after visiting a baseUrl the first time
|
||||
if (vm_proc)
|
||||
return cockpit_url;
|
||||
|
||||
// no, start a new VM
|
||||
return new Promise((resolve, reject) => {
|
||||
let proc = child_process.spawn("bots/machine/testvm.py", [image],
|
||||
{ stdio: ["pipe", "pipe", "inherit"] });
|
||||
let buf = "";
|
||||
vm_proc = proc.pid;
|
||||
proc.stdout.on("data", data => {
|
||||
buf += data.toString();
|
||||
if (buf.indexOf("\nRUNNING\n") > 0) {
|
||||
let lines = buf.split("\n");
|
||||
ssh_args = lines[0].split(" ").slice(1);
|
||||
cockpit_url = lines[1];
|
||||
resolve(cockpit_url);
|
||||
}
|
||||
});
|
||||
proc.on("error", err => reject (err));
|
||||
});
|
||||
},
|
||||
|
||||
stopVM: () => {
|
||||
process.kill(vm_proc);
|
||||
let p = waitpid(vm_proc);
|
||||
p.then(() => { vm_proc = null; });
|
||||
return p;
|
||||
},
|
||||
|
||||
runVM: command => {
|
||||
res = child_process.spawnSync("ssh", ssh_args.concat(command),
|
||||
{ stdio: ["pipe", "pipe", "inherit"], encoding: "UTF-8" });
|
||||
if (res.status)
|
||||
throw new Error(`Command "${command} failed with code ${res.status}`);
|
||||
return res.stdout;
|
||||
}
|
||||
});
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue