mirror of
https://github.com/ansible/awx.git
synced 2026-05-12 03:47:36 -02:30
add e2e test for job and workflow template copy
This commit is contained in:
@@ -10,11 +10,10 @@ import {
|
|||||||
} from './api';
|
} from './api';
|
||||||
|
|
||||||
const session = `e2e-${uuid().substr(0, 8)}`;
|
const session = `e2e-${uuid().substr(0, 8)}`;
|
||||||
|
|
||||||
const store = {};
|
const store = {};
|
||||||
|
|
||||||
const getOrCreate = (endpoint, data) => {
|
const getOrCreate = (endpoint, data, unique = ['name', 'username', 'id']) => {
|
||||||
const identifier = Object.keys(data).find(key => ['name', 'username'].includes(key));
|
const identifier = Object.keys(data).find(key => unique.includes(key));
|
||||||
|
|
||||||
if (identifier === undefined) {
|
if (identifier === undefined) {
|
||||||
throw new Error('A unique key value must be provided.');
|
throw new Error('A unique key value must be provided.');
|
||||||
@@ -22,12 +21,10 @@ const getOrCreate = (endpoint, data) => {
|
|||||||
|
|
||||||
const identity = data[identifier];
|
const identity = data[identifier];
|
||||||
|
|
||||||
if (store[endpoint] && store[endpoint][identity]) {
|
store[endpoint] = store[endpoint] || {};
|
||||||
return store[endpoint][identity].then(created => created.data);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!store[endpoint]) {
|
if (store[endpoint][identity]) {
|
||||||
store[endpoint] = {};
|
return store[endpoint][identity].then(created => created.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
const query = { params: { [identifier]: identity } };
|
const query = { params: { [identifier]: identity } };
|
||||||
@@ -246,6 +243,47 @@ const getJobTemplate = (namespace = session) => {
|
|||||||
})));
|
})));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getWorkflowTemplate = (namespace = session) => {
|
||||||
|
const endpoint = '/workflow_job_templates/';
|
||||||
|
|
||||||
|
const workflowTemplatePromise = getOrganization(namespace)
|
||||||
|
.then(organization => getOrCreate(endpoint, {
|
||||||
|
name: `${namespace}-workflow-template`
|
||||||
|
organization: organization.id,
|
||||||
|
variables: '---',
|
||||||
|
extra_vars: '',
|
||||||
|
}));
|
||||||
|
|
||||||
|
const resources = [
|
||||||
|
workflowTemplatePromise,
|
||||||
|
getInventorySource(namespace),
|
||||||
|
getUpdatedProject(namespace),
|
||||||
|
getJobTemplate(namespace),
|
||||||
|
];
|
||||||
|
|
||||||
|
const workflowNodePromise = all(resources)
|
||||||
|
.then(spread((workflowTemplate, source, project, jobTemplate) => {
|
||||||
|
const workflowNodes = workflowTemplate.related.workflow_nodes;
|
||||||
|
const unique = 'unified_job_template';
|
||||||
|
|
||||||
|
const nodes = [
|
||||||
|
getOrCreate(workflowNodes, { [unique]: project.id }, [unique]),
|
||||||
|
getOrCreate(workflowNodes, { [unique]: jobTemplate.id }, [unique]),
|
||||||
|
getOrCreate(workflowNodes, { [unique]: source.id }, [unique]),
|
||||||
|
];
|
||||||
|
|
||||||
|
const createSuccessNodes = (projectNode, jobNode, sourceNode) => all([
|
||||||
|
getOrCreate(projectNode.related.success_nodes, { id: jobNode.id }),
|
||||||
|
getOrCreate(jobNode.related.success_nodes, { id: sourceNode.id }),
|
||||||
|
]);
|
||||||
|
|
||||||
|
return all(nodes).then(spread(createSuccessNodes));
|
||||||
|
}));
|
||||||
|
|
||||||
|
return all([workflowTemplatePromise, workflowNodePromise])
|
||||||
|
.then(spread((workflowTemplate, nodes) => workflowTemplate));
|
||||||
|
};
|
||||||
|
|
||||||
const getAuditor = (namespace = session) => getOrganization(namespace)
|
const getAuditor = (namespace = session) => getOrganization(namespace)
|
||||||
.then(organization => getOrCreate('/users/', {
|
.then(organization => getOrCreate('/users/', {
|
||||||
username: `auditor-${uuid().substr(0, 8)}`,
|
username: `auditor-${uuid().substr(0, 8)}`,
|
||||||
@@ -334,21 +372,23 @@ module.exports = {
|
|||||||
getAdminAWSCredential,
|
getAdminAWSCredential,
|
||||||
getAdminMachineCredential,
|
getAdminMachineCredential,
|
||||||
getAuditor,
|
getAuditor,
|
||||||
|
getHost,
|
||||||
getInventory,
|
getInventory,
|
||||||
getInventoryScript,
|
getInventoryScript,
|
||||||
getInventorySource,
|
getInventorySource,
|
||||||
getInventorySourceSchedule,
|
getInventorySourceSchedule,
|
||||||
|
getJob,
|
||||||
getJobTemplate,
|
getJobTemplate,
|
||||||
getJobTemplateAdmin,
|
getJobTemplateAdmin,
|
||||||
getJobTemplateSchedule,
|
getJobTemplateSchedule,
|
||||||
getNotificationTemplate,
|
getNotificationTemplate,
|
||||||
getOrCreate,
|
|
||||||
getOrganization,
|
getOrganization,
|
||||||
|
getProject,
|
||||||
getProjectAdmin,
|
getProjectAdmin,
|
||||||
getSmartInventory,
|
getSmartInventory,
|
||||||
getTeam,
|
getTeam,
|
||||||
getUpdatedProject,
|
getUpdatedProject,
|
||||||
getUser,
|
getUser,
|
||||||
getJob,
|
getUser,
|
||||||
getHost,
|
getWorkflowTemplate,
|
||||||
};
|
};
|
||||||
|
|||||||
161
awx/ui/test/e2e/tests/test-templates-list-actions.js
Normal file
161
awx/ui/test/e2e/tests/test-templates-list-actions.js
Normal file
@@ -0,0 +1,161 @@
|
|||||||
|
import {
|
||||||
|
getInventorySource,
|
||||||
|
getJobTemplate,
|
||||||
|
getProject,
|
||||||
|
getWorkflowTemplate
|
||||||
|
} from '../fixtures';
|
||||||
|
|
||||||
|
let data;
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
before: (client, done) => {
|
||||||
|
const resources = [
|
||||||
|
getInventorySource('test-actions'),
|
||||||
|
getJobTemplate('test-actions'),
|
||||||
|
getProject('test-actions'),
|
||||||
|
getWorkflowTemplate('test-actions'),
|
||||||
|
];
|
||||||
|
|
||||||
|
Promise.all(resources)
|
||||||
|
.then(([source, template, project, workflow]) => {
|
||||||
|
data = { source, template, project, workflow };
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
'copy job template': client => {
|
||||||
|
const templates = client.page.templates();
|
||||||
|
|
||||||
|
client.useCss();
|
||||||
|
client.resizeWindow(1200, 800);
|
||||||
|
client.login();
|
||||||
|
client.waitForAngular();
|
||||||
|
|
||||||
|
templates.navigate();
|
||||||
|
templates.waitForElementVisible('div.spinny');
|
||||||
|
templates.waitForElementNotVisible('div.spinny');
|
||||||
|
|
||||||
|
templates.expect.element('smart-search').visible;
|
||||||
|
templates.expect.element('smart-search input').enabled;
|
||||||
|
|
||||||
|
templates
|
||||||
|
.sendKeys('smart-search input', `id:>${data.template.id - 1} id:<${data.template.id + 1}`)
|
||||||
|
.sendKeys('smart-search input', client.Keys.ENTER);
|
||||||
|
|
||||||
|
templates.waitForElementVisible('div.spinny');
|
||||||
|
templates.waitForElementNotVisible('div.spinny');
|
||||||
|
|
||||||
|
templates.expect.element('.at-Panel-headingTitleBadge').text.equal('1');
|
||||||
|
templates.expect.element(`#row-${data.template.id}`).visible;
|
||||||
|
templates.expect.element('i[class*="copy"]').visible;
|
||||||
|
templates.expect.element('i[class*="copy"]').enabled;
|
||||||
|
|
||||||
|
templates.click('i[class*="copy"]');
|
||||||
|
templates.waitForElementVisible('div.spinny');
|
||||||
|
templates.waitForElementNotVisible('div.spinny');
|
||||||
|
|
||||||
|
templates.expect.element('#job_template_form').visible;
|
||||||
|
templates.section.addJobTemplate.expect.element('@title').visible;
|
||||||
|
templates.section.addJobTemplate.expect.element('@title').text.contain(data.template.name);
|
||||||
|
templates.section.addJobTemplate.expect.element('@title').text.not.equal(data.template.name);
|
||||||
|
templates.expect.element('@save').visible;
|
||||||
|
templates.expect.element('@save').enabled;
|
||||||
|
|
||||||
|
client.end();
|
||||||
|
},
|
||||||
|
'copy workflow template': client => {
|
||||||
|
const templates = client.page.templates();
|
||||||
|
|
||||||
|
client.useCss();
|
||||||
|
client.resizeWindow(1200, 800);
|
||||||
|
client.login();
|
||||||
|
client.waitForAngular();
|
||||||
|
|
||||||
|
templates.navigate();
|
||||||
|
templates.waitForElementVisible('div.spinny');
|
||||||
|
templates.waitForElementNotVisible('div.spinny');
|
||||||
|
|
||||||
|
templates.expect.element('smart-search').visible;
|
||||||
|
templates.expect.element('smart-search input').enabled;
|
||||||
|
|
||||||
|
templates
|
||||||
|
.sendKeys('smart-search input', `id:>${data.workflow.id - 1} id:<${data.workflow.id + 1}`)
|
||||||
|
.sendKeys('smart-search input', client.Keys.ENTER);
|
||||||
|
|
||||||
|
templates.waitForElementVisible('div.spinny');
|
||||||
|
templates.waitForElementNotVisible('div.spinny');
|
||||||
|
|
||||||
|
templates.expect.element('.at-Panel-headingTitleBadge').text.equal('1');
|
||||||
|
templates.expect.element(`#row-${data.workflow.id}`).visible;
|
||||||
|
templates.expect.element('i[class*="copy"]').visible;
|
||||||
|
templates.expect.element('i[class*="copy"]').enabled;
|
||||||
|
|
||||||
|
templates
|
||||||
|
.click('i[class*="copy"]')
|
||||||
|
.waitForElementVisible('div.spinny')
|
||||||
|
.waitForElementNotVisible('div.spinny')
|
||||||
|
.waitForAngular();
|
||||||
|
|
||||||
|
templates.expect.element('#workflow_job_template_form').visible;
|
||||||
|
templates.section.editWorkflowJobTemplate.expect.element('@title').visible;
|
||||||
|
templates.section.editWorkflowJobTemplate.expect.element('@title').text.contain(data.workflow.name);
|
||||||
|
templates.section.editWorkflowJobTemplate.expect.element('@title').text.not.equal(data.workflow.name);
|
||||||
|
|
||||||
|
templates.expect.element('@save').visible;
|
||||||
|
templates.expect.element('@save').enabled;
|
||||||
|
|
||||||
|
client
|
||||||
|
.useXpath()
|
||||||
|
.pause(1000)
|
||||||
|
.waitForElementVisible('//*[text()=" Workflow Editor"]')
|
||||||
|
.click('//*[text()=" Workflow Editor"]')
|
||||||
|
.useCss()
|
||||||
|
.waitForElementVisible('div.spinny')
|
||||||
|
.waitForElementNotVisible('div.spinny')
|
||||||
|
.waitForAngular();
|
||||||
|
|
||||||
|
client.expect.element('#workflow-modal-dialog').visible;
|
||||||
|
client.expect.element('#workflow-modal-dialog span[class^="badge"]').visible;
|
||||||
|
client.expect.element('#workflow-modal-dialog span[class^="badge"]').text.equal('3');
|
||||||
|
client.expect.element('div[class="WorkflowMaker-title"]').visible;
|
||||||
|
client.expect.element('div[class="WorkflowMaker-title"]').text.contain(data.workflow.name);
|
||||||
|
client.expect.element('div[class="WorkflowMaker-title"]').text.not.equal(data.workflow.name);
|
||||||
|
|
||||||
|
client.expect.element('#workflow-modal-dialog i[class*="fa-cog"]').visible;
|
||||||
|
client.expect.element('#workflow-modal-dialog i[class*="fa-cog"]').enabled;
|
||||||
|
|
||||||
|
client.click('#workflow-modal-dialog i[class*="fa-cog"]');
|
||||||
|
|
||||||
|
client.waitForElementVisible('workflow-controls');
|
||||||
|
client.waitForElementVisible('div[class*="-zoomPercentage"]');
|
||||||
|
|
||||||
|
client.click('i[class*="fa-home"]').expect.element('div[class*="-zoomPercentage"]').text.equal('100%');
|
||||||
|
client.click('i[class*="fa-minus"]').expect.element('div[class*="-zoomPercentage"]').text.equal('90%');
|
||||||
|
client.click('i[class*="fa-minus"]').expect.element('div[class*="-zoomPercentage"]').text.equal('80%');
|
||||||
|
client.click('i[class*="fa-minus"]').expect.element('div[class*="-zoomPercentage"]').text.equal('70%');
|
||||||
|
client.click('i[class*="fa-minus"]').expect.element('div[class*="-zoomPercentage"]').text.equal('60%');
|
||||||
|
|
||||||
|
client.expect.element('#node-1').visible;
|
||||||
|
client.expect.element('#node-2').visible;
|
||||||
|
client.expect.element('#node-3').visible;
|
||||||
|
client.expect.element('#node-4').visible;
|
||||||
|
|
||||||
|
client.expect.element('#node-1 text').text.not.equal('').after(5000);
|
||||||
|
client.expect.element('#node-2 text').text.not.equal('').after(5000);
|
||||||
|
client.expect.element('#node-3 text').text.not.equal('').after(5000);
|
||||||
|
client.expect.element('#node-4 text').text.not.equal('').after(5000);
|
||||||
|
|
||||||
|
const checkNodeText = (selector, text) => client.getText(selector, ({ value }) => {
|
||||||
|
client.assert.equal(text.indexOf(value.replace('...', '')) >= 0, true);
|
||||||
|
});
|
||||||
|
|
||||||
|
checkNodeText('#node-1 text', 'START');
|
||||||
|
checkNodeText('#node-2 text', data.project.name);
|
||||||
|
checkNodeText('#node-3 text', data.template.name);
|
||||||
|
checkNodeText('#node-4 text', data.source.name);
|
||||||
|
|
||||||
|
templates.expect.element('@save').visible;
|
||||||
|
templates.expect.element('@save').enabled;
|
||||||
|
|
||||||
|
client.end();
|
||||||
|
}
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user