Merge pull request #2620 from mabashian/2557-copy

Change post-copy behavior
This commit is contained in:
Michael Abashian
2018-07-20 11:00:48 -04:00
committed by GitHub
15 changed files with 326 additions and 53 deletions

View File

@@ -22,7 +22,8 @@ function ListTemplatesController(
strings, strings,
Wait, Wait,
qs, qs,
GetBasePath GetBasePath,
ngToast
) { ) {
const vm = this || {}; const vm = this || {};
const [jobTemplate, workflowTemplate] = resolvedModels; const [jobTemplate, workflowTemplate] = resolvedModels;
@@ -57,7 +58,7 @@ function ListTemplatesController(
}; };
vm.dataset = Dataset.data; vm.dataset = Dataset.data;
vm.templates = Dataset.data.results; vm.templates = Dataset.data.results;
$scope.$watch('vm.dataset.count', () => { $scope.$watch('vm.dataset.count', () => {
$scope.$emit('updateCount', vm.dataset.count, 'templates'); $scope.$emit('updateCount', vm.dataset.count, 'templates');
}); });
@@ -201,9 +202,21 @@ function ListTemplatesController(
jobTemplate jobTemplate
.create('get', template.id) .create('get', template.id)
.then(model => model.copy()) .then(model => model.copy())
.then(({ id }) => { .then((copiedJT) => {
const params = { job_template_id: id }; ngToast.success({
$state.go('templates.editJobTemplate', params, { reload: true }); content: `
<div class="Toast-wrapper">
<div class="Toast-icon">
<i class="fa fa-check-circle Toast-successIcon"></i>
</div>
<div>
${strings.get('SUCCESSFUL_CREATION', copiedJT.name)}
</div>
</div>`,
dismissButton: false,
dismissOnTimeout: true
});
$state.go('.', null, { reload: true });
}) })
.catch(createErrorHandler('copy job template', 'POST')) .catch(createErrorHandler('copy job template', 'POST'))
.finally(() => Wait('stop')); .finally(() => Wait('stop'));
@@ -219,9 +232,21 @@ function ListTemplatesController(
$('#prompt-modal').modal('hide'); $('#prompt-modal').modal('hide');
Wait('start'); Wait('start');
model.copy() model.copy()
.then(({ id }) => { .then((copiedWFJT) => {
const params = { workflow_job_template_id: id }; ngToast.success({
$state.go('templates.editWorkflowJobTemplate', params, { reload: true }); content: `
<div class="Toast-wrapper">
<div class="Toast-icon">
<i class="fa fa-check-circle Toast-successIcon"></i>
</div>
<div>
${strings.get('SUCCESSFUL_CREATION', copiedWFJT.name)}
</div>
</div>`,
dismissButton: false,
dismissOnTimeout: true
});
$state.go('.', null, { reload: true });
}) })
.catch(createErrorHandler('copy workflow', 'POST')) .catch(createErrorHandler('copy workflow', 'POST'))
.finally(() => Wait('stop')); .finally(() => Wait('stop'));
@@ -360,7 +385,8 @@ ListTemplatesController.$inject = [
'TemplatesStrings', 'TemplatesStrings',
'Wait', 'Wait',
'QuerySet', 'QuerySet',
'GetBasePath' 'GetBasePath',
'ngToast'
]; ];
export default ListTemplatesController; export default ListTemplatesController;

View File

@@ -2349,3 +2349,14 @@ body {
margin-top: .3em; margin-top: .3em;
margin-bottom: .3em; margin-bottom: .3em;
} }
.Toast-wrapper {
display: flex;
max-width: 250px;
}
.Toast-icon {
display: flex;
align-items: center;
justify-content: center;
}

View File

@@ -72,6 +72,7 @@ function BaseStringService (namespace) {
this.COPY = t.s('COPY'); this.COPY = t.s('COPY');
this.YES = t.s('YES'); this.YES = t.s('YES');
this.CLOSE = t.s('CLOSE'); this.CLOSE = t.s('CLOSE');
this.SUCCESSFUL_CREATION = resource => t.s('{{ resource }} successfully created', { resource });
this.deleteResource = { this.deleteResource = {
HEADER: t.s('Delete'), HEADER: t.s('Delete'),

View File

@@ -6,10 +6,10 @@
export default ['$scope', 'Rest', 'CredentialList', 'Prompt', 'ProcessErrors', 'GetBasePath', export default ['$scope', 'Rest', 'CredentialList', 'Prompt', 'ProcessErrors', 'GetBasePath',
'Wait', '$state', '$filter', 'rbacUiControlService', 'Dataset', 'credentialType', 'i18n', 'Wait', '$state', '$filter', 'rbacUiControlService', 'Dataset', 'credentialType', 'i18n',
'CredentialModel', 'CredentialsStrings', 'CredentialModel', 'CredentialsStrings', 'ngToast',
function($scope, Rest, CredentialList, Prompt, function($scope, Rest, CredentialList, Prompt,
ProcessErrors, GetBasePath, Wait, $state, $filter, rbacUiControlService, Dataset, ProcessErrors, GetBasePath, Wait, $state, $filter, rbacUiControlService, Dataset,
credentialType, i18n, Credential, CredentialsStrings) { credentialType, i18n, Credential, CredentialsStrings, ngToast) {
const credential = new Credential(); const credential = new Credential();
@@ -93,9 +93,21 @@ export default ['$scope', 'Rest', 'CredentialList', 'Prompt', 'ProcessErrors', '
Wait('start'); Wait('start');
new Credential('get', credential.id) new Credential('get', credential.id)
.then(model => model.copy()) .then(model => model.copy())
.then(({ id }) => { .then((copiedCred) => {
const params = { credential_id: id }; ngToast.success({
$state.go('credentials.edit', params, { reload: true }); content: `
<div class="Toast-wrapper">
<div class="Toast-icon">
<i class="fa fa-check-circle Toast-successIcon"></i>
</div>
<div>
${CredentialsStrings.get('SUCCESSFUL_CREATION', copiedCred.name)}
</div>
</div>`,
dismissButton: false,
dismissOnTimeout: true
});
$state.go('.', null, { reload: true });
}) })
.catch(({ data, status }) => { .catch(({ data, status }) => {
const params = { hdr: 'Error!', msg: `Call to copy failed. Return status: ${status}` }; const params = { hdr: 'Error!', msg: `Call to copy failed. Return status: ${status}` };

View File

@@ -13,7 +13,8 @@
function InventoriesList($scope, function InventoriesList($scope,
$filter, Rest, InventoryList, Prompt, $filter, Rest, InventoryList, Prompt,
ProcessErrors, GetBasePath, Wait, $state, ProcessErrors, GetBasePath, Wait, $state,
Dataset, canAdd, i18n, Inventory, InventoryHostsStrings) { Dataset, canAdd, i18n, Inventory, InventoryHostsStrings,
ngToast) {
let inventory = new Inventory(); let inventory = new Inventory();
@@ -82,7 +83,22 @@ function InventoriesList($scope,
Wait('start'); Wait('start');
new Inventory('get', inventory.id) new Inventory('get', inventory.id)
.then(model => model.copy()) .then(model => model.copy())
.then(copy => $scope.editInventory(copy, true)) .then(copiedInv => {
ngToast.success({
content: `
<div class="Toast-wrapper">
<div class="Toast-icon">
<i class="fa fa-check-circle Toast-successIcon"></i>
</div>
<div>
${InventoryHostsStrings.get('SUCCESSFUL_CREATION', copiedInv.name)}
</div>
</div>`,
dismissButton: false,
dismissOnTimeout: true
});
$state.go('.', null, { reload: true });
})
.catch(({ data, status }) => { .catch(({ data, status }) => {
const params = { hdr: 'Error!', msg: `Call to copy failed. Return status: ${status}` }; const params = { hdr: 'Error!', msg: `Call to copy failed. Return status: ${status}` };
ProcessErrors($scope, data, status, null, params); ProcessErrors($scope, data, status, null, params);
@@ -182,5 +198,5 @@ export default ['$scope',
'$filter', 'Rest', 'InventoryList', 'Prompt', '$filter', 'Rest', 'InventoryList', 'Prompt',
'ProcessErrors', 'GetBasePath', 'Wait', 'ProcessErrors', 'GetBasePath', 'Wait',
'$state', 'Dataset', 'canAdd', 'i18n', 'InventoryModel', '$state', 'Dataset', 'canAdd', 'i18n', 'InventoryModel',
'InventoryHostsStrings', InventoriesList 'InventoryHostsStrings', 'ngToast', InventoriesList
]; ];

View File

@@ -7,12 +7,12 @@
export default ['$rootScope', '$scope', 'Wait', 'InventoryScriptsList', export default ['$rootScope', '$scope', 'Wait', 'InventoryScriptsList',
'GetBasePath', 'Rest', 'ProcessErrors', 'Prompt', '$state', '$filter', 'GetBasePath', 'Rest', 'ProcessErrors', 'Prompt', '$state', '$filter',
'Dataset', 'rbacUiControlService', 'InventoryScriptModel', 'InventoryScriptsStrings', 'Dataset', 'rbacUiControlService', 'InventoryScriptModel', 'InventoryScriptsStrings',
'i18n', 'i18n', 'ngToast',
function( function(
$rootScope, $scope, Wait, InventoryScriptsList, $rootScope, $scope, Wait, InventoryScriptsList,
GetBasePath, Rest, ProcessErrors, Prompt, $state, $filter, GetBasePath, Rest, ProcessErrors, Prompt, $state, $filter,
Dataset, rbacUiControlService, InventoryScript, InventoryScriptsStrings, Dataset, rbacUiControlService, InventoryScript, InventoryScriptsStrings,
i18n i18n, ngToast
) { ) {
let inventoryScript = new InventoryScript(); let inventoryScript = new InventoryScript();
var defaultUrl = GetBasePath('inventory_scripts'), var defaultUrl = GetBasePath('inventory_scripts'),
@@ -51,9 +51,21 @@ export default ['$rootScope', '$scope', 'Wait', 'InventoryScriptsList',
Wait('start'); Wait('start');
new InventoryScript('get', inventoryScript.id) new InventoryScript('get', inventoryScript.id)
.then(model => model.copy()) .then(model => model.copy())
.then(({ id }) => { .then((copiedInvScript) => {
const params = { inventory_script_id: id }; ngToast.success({
$state.go('inventoryScripts.edit', params, { reload: true }); content: `
<div class="Toast-wrapper">
<div class="Toast-icon">
<i class="fa fa-check-circle Toast-successIcon"></i>
</div>
<div>
${InventoryScriptsStrings.get('SUCCESSFUL_CREATION', copiedInvScript.name)}
</div>
</div>`,
dismissButton: false,
dismissOnTimeout: true
});
$state.go('.', null, { reload: true });
}) })
.catch(({ data, status }) => { .catch(({ data, status }) => {
const params = { hdr: 'Error!', msg: `Call to copy failed. Return status: ${status}` }; const params = { hdr: 'Error!', msg: `Call to copy failed. Return status: ${status}` };

View File

@@ -7,12 +7,12 @@
export default ['$scope', 'Wait', 'NotificationTemplatesList', export default ['$scope', 'Wait', 'NotificationTemplatesList',
'GetBasePath', 'Rest', 'ProcessErrors', 'Prompt', '$state', 'GetBasePath', 'Rest', 'ProcessErrors', 'Prompt', '$state',
'ngToast', '$filter', 'Dataset', 'rbacUiControlService', 'ngToast', '$filter', 'Dataset', 'rbacUiControlService',
'i18n', 'NotificationTemplate', 'i18n', 'NotificationTemplate', 'AppStrings',
function( function(
$scope, Wait, NotificationTemplatesList, $scope, Wait, NotificationTemplatesList,
GetBasePath, Rest, ProcessErrors, Prompt, $state, GetBasePath, Rest, ProcessErrors, Prompt, $state,
ngToast, $filter, Dataset, rbacUiControlService, ngToast, $filter, Dataset, rbacUiControlService,
i18n, NotificationTemplate) { i18n, NotificationTemplate, AppStrings) {
var defaultUrl = GetBasePath('notification_templates'), var defaultUrl = GetBasePath('notification_templates'),
list = NotificationTemplatesList; list = NotificationTemplatesList;
@@ -92,12 +92,21 @@
Wait('start'); Wait('start');
new NotificationTemplate('get', notificationTemplate.id) new NotificationTemplate('get', notificationTemplate.id)
.then(model => model.copy()) .then(model => model.copy())
.then(({ id }) => { .then((copiedNotification) => {
const params = { ngToast.success({
notification_template_id: id, content: `
notification_template: this.notification_templates <div class="Toast-wrapper">
}; <div class="Toast-icon">
$state.go('notifications.edit', params, { reload: true }); <i class="fa fa-check-circle Toast-successIcon"></i>
</div>
<div>
${AppStrings.get('SUCCESSFUL_CREATION', copiedNotification.name)}
</div>
</div>`,
dismissButton: false,
dismissOnTimeout: true
});
$state.go('.', null, { reload: true });
}) })
.catch(({ data, status }) => { .catch(({ data, status }) => {
const params = { hdr: 'Error!', msg: `Call to copy failed. Return status: ${status}` }; const params = { hdr: 'Error!', msg: `Call to copy failed. Return status: ${status}` };

View File

@@ -8,11 +8,11 @@ export default ['$scope', '$rootScope', '$log', 'Rest', 'Alert',
'ProjectList', 'Prompt', 'ProcessErrors', 'GetBasePath', 'ProjectUpdate', 'ProjectList', 'Prompt', 'ProcessErrors', 'GetBasePath', 'ProjectUpdate',
'Wait', 'Empty', 'Find', 'GetProjectIcon', 'GetProjectToolTip', '$filter', 'Wait', 'Empty', 'Find', 'GetProjectIcon', 'GetProjectToolTip', '$filter',
'$state', 'rbacUiControlService', 'Dataset', 'i18n', 'QuerySet', 'ProjectModel', '$state', 'rbacUiControlService', 'Dataset', 'i18n', 'QuerySet', 'ProjectModel',
'ProjectsStrings', 'ProjectsStrings', 'ngToast',
function($scope, $rootScope, $log, Rest, Alert, ProjectList, function($scope, $rootScope, $log, Rest, Alert, ProjectList,
Prompt, ProcessErrors, GetBasePath, ProjectUpdate, Wait, Empty, Find, Prompt, ProcessErrors, GetBasePath, ProjectUpdate, Wait, Empty, Find,
GetProjectIcon, GetProjectToolTip, $filter, $state, rbacUiControlService, GetProjectIcon, GetProjectToolTip, $filter, $state, rbacUiControlService,
Dataset, i18n, qs, Project, ProjectsStrings) { Dataset, i18n, qs, Project, ProjectsStrings, ngToast) {
let project = new Project(); let project = new Project();
@@ -156,9 +156,21 @@ export default ['$scope', '$rootScope', '$log', 'Rest', 'Alert',
Wait('start'); Wait('start');
new Project('get', project.id) new Project('get', project.id)
.then(model => model.copy()) .then(model => model.copy())
.then(({ id }) => { .then((copiedProj) => {
const params = { project_id: id }; ngToast.success({
$state.go('projects.edit', params, { reload: true }); content: `
<div class="Toast-wrapper">
<div class="Toast-icon">
<i class="fa fa-check-circle Toast-successIcon"></i>
</div>
<div>
${ProjectsStrings.get('SUCCESSFUL_CREATION', copiedProj.name)}
</div>
</div>`,
dismissButton: false,
dismissOnTimeout: true
});
$state.go('.', null, { reload: true });
}) })
.catch(({ data, status }) => { .catch(({ data, status }) => {
const params = { hdr: 'Error!', msg: `Call to copy failed. Return status: ${status}` }; const params = { hdr: 'Error!', msg: `Call to copy failed. Return status: ${status}` };

View File

@@ -57,6 +57,18 @@ const getInventory = (namespace = session) => getOrganization(namespace)
variables: JSON.stringify({ ansible_connection: 'local' }), variables: JSON.stringify({ ansible_connection: 'local' }),
}, ['name', 'inventory']).then(() => inventory))); }, ['name', 'inventory']).then(() => inventory)));
const getInventoryNoSource = (namespace = session) => getOrganization(namespace)
.then(organization => getOrCreate('/inventories/', {
name: `${namespace}-inventory-nosource`,
description: namespace,
organization: organization.id
}).then(inventory => getOrCreate('/hosts/', {
name: `${namespace}-host`,
description: namespace,
inventory: inventory.id,
variables: JSON.stringify({ ansible_connection: 'local' }),
}, ['name', 'inventory']).then(() => inventory)));
const getHost = (namespace = session) => getInventory(namespace) const getHost = (namespace = session) => getInventory(namespace)
.then(inventory => getOrCreate('/hosts/', { .then(inventory => getOrCreate('/hosts/', {
name: `${namespace}-host`, name: `${namespace}-host`,
@@ -365,6 +377,7 @@ module.exports = {
getAuditor, getAuditor,
getHost, getHost,
getInventory, getInventory,
getInventoryNoSource,
getInventoryScript, getInventoryScript,
getInventorySource, getInventorySource,
getInventorySourceSchedule, getInventorySourceSchedule,

View File

@@ -38,6 +38,24 @@ module.exports = {
credentials.waitForElementVisible('div.spinny'); credentials.waitForElementVisible('div.spinny');
credentials.waitForElementNotVisible('div.spinny'); credentials.waitForElementNotVisible('div.spinny');
const activityStream = 'bread-crumb > div i[class$="icon-activity-stream"]';
const activityRow = '#activities_table tr td[class*="description-column"] a';
const toast = 'div[class="Toast-icon"]';
credentials.waitForElementNotPresent(toast);
credentials.expect.element(activityStream).visible;
credentials.expect.element(activityStream).enabled;
credentials.click(activityStream);
credentials.waitForElementVisible('div.spinny');
credentials.waitForElementNotVisible('div.spinny');
client
.waitForElementVisible(activityRow)
.click(activityRow);
credentials.waitForElementVisible('div.spinny');
credentials.waitForElementNotVisible('div.spinny');
credentials.expect.element('div[ui-view="edit"] form').visible; credentials.expect.element('div[ui-view="edit"] form').visible;
credentials.section.edit.expect.element('@title').visible; credentials.section.edit.expect.element('@title').visible;
credentials.section.edit.expect.element('@title').text.contain(data.credential.name); credentials.section.edit.expect.element('@title').text.contain(data.credential.name);

View File

@@ -1,12 +1,19 @@
import { getInventory } from '../fixtures'; import { getInventory, getInventoryNoSource } from '../fixtures';
const data = {}; let data;
module.exports = { module.exports = {
before: (client, done) => { before: (client, done) => {
getInventory('test-actions') const resources = [
.then(obj => { data.inventory = obj; }) getInventory('test-actions'),
.then(done); getInventoryNoSource('test-actions'),
];
Promise.all(resources)
.then(([inventory, inventoryNoSource]) => {
data = { inventory, inventoryNoSource };
done();
});
}, },
'copy inventory': client => { 'copy inventory': client => {
const inventories = client.page.inventories(); const inventories = client.page.inventories();
@@ -23,6 +30,63 @@ module.exports = {
inventories.section.list.expect.element('smart-search').visible; inventories.section.list.expect.element('smart-search').visible;
inventories.section.list.section.search.expect.element('@input').enabled; inventories.section.list.section.search.expect.element('@input').enabled;
inventories.section.list.section.search
.sendKeys('@input', `id:>${data.inventoryNoSource.id - 1} id:<${data.inventoryNoSource.id + 1}`)
.sendKeys('@input', client.Keys.ENTER);
inventories.waitForElementVisible('div.spinny');
inventories.waitForElementNotVisible('div.spinny');
inventories.expect.element(`#inventories_table tr[id="${data.inventoryNoSource.id}"]`).visible;
inventories.expect.element('i[class*="copy"]').visible;
inventories.expect.element('i[class*="copy"]').enabled;
inventories.click('i[class*="copy"]');
inventories.waitForElementVisible('div.spinny');
inventories.waitForElementNotVisible('div.spinny');
const activityStream = 'bread-crumb > div i[class$="icon-activity-stream"]';
const activityRow = '#activities_table tr td[class*="description-column"] a';
const toast = 'div[class="Toast-icon"]';
inventories.waitForElementNotPresent(toast);
inventories.expect.element(activityStream).visible;
inventories.expect.element(activityStream).enabled;
inventories.click(activityStream);
inventories.waitForElementVisible('div.spinny');
inventories.waitForElementNotVisible('div.spinny');
client
.waitForElementVisible(activityRow)
.click(activityRow);
inventories.waitForElementVisible('div.spinny');
inventories.waitForElementNotVisible('div.spinny');
inventories.expect.element('#inventory_form').visible;
inventories.section.editStandardInventory.expect.element('@title').visible;
inventories.section.editStandardInventory.expect.element('@title').text.contain(data.inventoryNoSource.name);
inventories.section.editStandardInventory.expect.element('@title').text.not.equal(data.inventoryNoSource.name);
inventories.expect.element('@save').visible;
inventories.expect.element('@save').enabled;
client.end();
},
'verify inventories with sources cannot be copied': client => {
const inventories = client.page.inventories();
client.useCss();
client.resizeWindow(1200, 800);
client.login();
client.waitForAngular();
inventories.load();
inventories.waitForElementVisible('div.spinny');
inventories.waitForElementNotVisible('div.spinny');
inventories.section.list.expect.element('smart-search').visible;
inventories.section.list.section.search.expect.element('@input').enabled;
inventories.section.list.section.search inventories.section.list.section.search
.sendKeys('@input', `id:>${data.inventory.id - 1} id:<${data.inventory.id + 1}`) .sendKeys('@input', `id:>${data.inventory.id - 1} id:<${data.inventory.id + 1}`)
.sendKeys('@input', client.Keys.ENTER); .sendKeys('@input', client.Keys.ENTER);
@@ -31,19 +95,8 @@ module.exports = {
inventories.waitForElementNotVisible('div.spinny'); inventories.waitForElementNotVisible('div.spinny');
inventories.expect.element(`#inventories_table tr[id="${data.inventory.id}"]`).visible; inventories.expect.element(`#inventories_table tr[id="${data.inventory.id}"]`).visible;
inventories.expect.element('i[class*="copy"]').visible; inventories.expect.element('#copy-action').visible;
inventories.expect.element('i[class*="copy"]').enabled; inventories.expect.element('#copy-action[class$="btn-disabled"]').present;
inventories.click('i[class*="copy"]');
inventories.waitForElementVisible('div.spinny');
inventories.waitForElementNotVisible('div.spinny');
inventories.expect.element('#inventory_form').visible;
inventories.section.editStandardInventory.expect.element('@title').visible;
inventories.section.editStandardInventory.expect.element('@title').text.contain(data.inventory.name);
inventories.section.editStandardInventory.expect.element('@title').text.not.equal(data.inventory.name);
inventories.expect.element('@save').visible;
inventories.expect.element('@save').enabled;
client.end(); client.end();
} }

View File

@@ -38,6 +38,24 @@ module.exports = {
inventoryScripts.waitForElementVisible('div.spinny'); inventoryScripts.waitForElementVisible('div.spinny');
inventoryScripts.waitForElementNotVisible('div.spinny'); inventoryScripts.waitForElementNotVisible('div.spinny');
const activityStream = 'bread-crumb > div i[class$="icon-activity-stream"]';
const activityRow = '#activities_table tr td[class*="description-column"] a';
const toast = 'div[class="Toast-icon"]';
inventoryScripts.waitForElementNotPresent(toast);
inventoryScripts.expect.element(activityStream).visible;
inventoryScripts.expect.element(activityStream).enabled;
inventoryScripts.click(activityStream);
inventoryScripts.waitForElementVisible('div.spinny');
inventoryScripts.waitForElementNotVisible('div.spinny');
client
.waitForElementVisible(activityRow)
.click(activityRow);
inventoryScripts.waitForElementVisible('div.spinny');
inventoryScripts.waitForElementNotVisible('div.spinny');
inventoryScripts.expect.element('#inventory_script_form').visible; inventoryScripts.expect.element('#inventory_script_form').visible;
inventoryScripts.section.edit.expect.element('@title').visible; inventoryScripts.section.edit.expect.element('@title').visible;
inventoryScripts.section.edit.expect.element('@title').text.contain(data.inventoryScript.name); inventoryScripts.section.edit.expect.element('@title').text.contain(data.inventoryScript.name);

View File

@@ -38,6 +38,24 @@ module.exports = {
notifications.waitForElementVisible('div.spinny'); notifications.waitForElementVisible('div.spinny');
notifications.waitForElementNotVisible('div.spinny'); notifications.waitForElementNotVisible('div.spinny');
const activityStream = 'bread-crumb > div i[class$="icon-activity-stream"]';
const activityRow = '#activities_table tr td[class*="description-column"] a';
const toast = 'div[class="Toast-icon"]';
notifications.waitForElementNotPresent(toast);
notifications.expect.element(activityStream).visible;
notifications.expect.element(activityStream).enabled;
notifications.click(activityStream);
notifications.waitForElementVisible('div.spinny');
notifications.waitForElementNotVisible('div.spinny');
client
.waitForElementVisible(activityRow)
.click(activityRow);
notifications.waitForElementVisible('div.spinny');
notifications.waitForElementNotVisible('div.spinny');
notifications.expect.element('#notification_template_form').visible; notifications.expect.element('#notification_template_form').visible;
notifications.section.edit.expect.element('@title').visible; notifications.section.edit.expect.element('@title').visible;
notifications.section.edit.expect.element('@title').text.contain(data.notification.name); notifications.section.edit.expect.element('@title').text.contain(data.notification.name);

View File

@@ -39,6 +39,24 @@ module.exports = {
projects.waitForElementVisible('div.spinny'); projects.waitForElementVisible('div.spinny');
projects.waitForElementNotVisible('div.spinny'); projects.waitForElementNotVisible('div.spinny');
const activityStream = 'bread-crumb > div i[class$="icon-activity-stream"]';
const activityRow = '#activities_table tr td[class*="description-column"] a';
const toast = 'div[class="Toast-icon"]';
projects.waitForElementNotPresent(toast);
projects.expect.element(activityStream).visible;
projects.expect.element(activityStream).enabled;
projects.click(activityStream);
projects.waitForElementVisible('div.spinny');
projects.waitForElementNotVisible('div.spinny');
client
.waitForElementVisible(activityRow)
.click(activityRow);
projects.waitForElementVisible('div.spinny');
projects.waitForElementNotVisible('div.spinny');
projects.expect.element('#project_form').visible; projects.expect.element('#project_form').visible;
projects.section.edit.expect.element('@title').visible; projects.section.edit.expect.element('@title').visible;
projects.section.edit.expect.element('@title').text.contain(data.project.name); projects.section.edit.expect.element('@title').text.contain(data.project.name);

View File

@@ -53,6 +53,24 @@ module.exports = {
templates.waitForElementVisible('div.spinny'); templates.waitForElementVisible('div.spinny');
templates.waitForElementNotVisible('div.spinny'); templates.waitForElementNotVisible('div.spinny');
const activityStream = 'bread-crumb > div i[class$="icon-activity-stream"]';
const activityRow = '#activities_table tr td[class*="description-column"] a';
const toast = 'div[class="Toast-icon"]';
templates.waitForElementNotPresent(toast);
templates.expect.element(activityStream).visible;
templates.expect.element(activityStream).enabled;
templates.click(activityStream);
templates.waitForElementVisible('div.spinny');
templates.waitForElementNotVisible('div.spinny');
client
.waitForElementVisible(activityRow)
.click(activityRow);
templates.waitForElementVisible('div.spinny');
templates.waitForElementNotVisible('div.spinny');
templates.expect.element('#job_template_form').visible; templates.expect.element('#job_template_form').visible;
templates.section.addJobTemplate.expect.element('@title').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.contain(data.template.name);
@@ -95,6 +113,24 @@ module.exports = {
.waitForElementNotVisible('div.spinny') .waitForElementNotVisible('div.spinny')
.waitForAngular(); .waitForAngular();
const activityStream = 'bread-crumb > div i[class$="icon-activity-stream"]';
const activityRow = '#activities_table tr td[class*="description-column"] a';
const toast = 'div[class="Toast-icon"]';
templates.waitForElementNotPresent(toast);
templates.expect.element(activityStream).visible;
templates.expect.element(activityStream).enabled;
templates.click(activityStream);
templates.waitForElementVisible('div.spinny');
templates.waitForElementNotVisible('div.spinny');
client
.waitForElementVisible(activityRow)
.click(activityRow);
templates.waitForElementVisible('div.spinny');
templates.waitForElementNotVisible('div.spinny');
templates.expect.element('#workflow_job_template_form').visible; templates.expect.element('#workflow_job_template_form').visible;
templates.section.editWorkflowJobTemplate.expect.element('@title').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.contain(data.workflow.name);