mirror of
https://github.com/ansible/awx.git
synced 2026-01-11 18:09:57 -03:30
Merge pull request #1344 from jakemcdermott/e2e-updates
e2e / nightwatch updates
This commit is contained in:
commit
7430856ac9
@ -33,13 +33,14 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"angular-mocks": "~1.6.6",
|
||||
"archiver": "^2.1.1",
|
||||
"axios": "^0.16.2",
|
||||
"babel-core": "^6.26.0",
|
||||
"babel-istanbul": "^0.12.2",
|
||||
"babel-loader": "^7.1.2",
|
||||
"babel-plugin-istanbul": "^4.1.5",
|
||||
"babel-preset-env": "^1.6.0",
|
||||
"chromedriver": "^2.31.0",
|
||||
"chromedriver": "^2.35.0",
|
||||
"clean-webpack-plugin": "^0.1.16",
|
||||
"copy-webpack-plugin": "^4.0.1",
|
||||
"css-loader": "^0.28.5",
|
||||
@ -80,7 +81,7 @@
|
||||
"load-grunt-configs": "^1.0.0",
|
||||
"load-grunt-tasks": "^3.5.0",
|
||||
"ngtemplate-loader": "^2.0.1",
|
||||
"nightwatch": "^0.9.16",
|
||||
"nightwatch": "^0.9.19",
|
||||
"node-object-hash": "^1.3.0",
|
||||
"phantomjs-prebuilt": "^2.1.12",
|
||||
"time-grunt": "^1.4.0",
|
||||
|
||||
@ -4,7 +4,6 @@
|
||||
docker exec -i tools_awx_1 sh <<-EOSH
|
||||
awx-manage createsuperuser --noinput --username=awx-e2e --email=null@ansible.com
|
||||
awx-manage update_password --username=awx-e2e --password=password
|
||||
make --directory=/awx_devel DATA_GEN_PRESET=e2e bulk_data
|
||||
EOSH
|
||||
|
||||
# run all of the tests with a live browser
|
||||
|
||||
@ -2,13 +2,13 @@
|
||||
version: '2'
|
||||
services:
|
||||
hub:
|
||||
image: selenium/hub:3.8.1-erbium
|
||||
image: selenium/hub
|
||||
ports:
|
||||
- 4444:4444
|
||||
chrome:
|
||||
image: selenium/node-chrome:3.8.1-erbium
|
||||
image: selenium/node-chrome
|
||||
# uncomment the two lines below to make tests watchable at vnc://localhost:secret@localhost:5900
|
||||
# image: selenium/node-chrome-debug:3.8.1-erbium
|
||||
# image: selenium/node-chrome-debug
|
||||
# ports: ['5900:5900']
|
||||
links:
|
||||
- hub
|
||||
@ -18,7 +18,7 @@ services:
|
||||
HUB_PORT_4444_TCP_ADDR: hub
|
||||
HUB_PORT_4444_TCP_PORT: 4444
|
||||
firefox:
|
||||
image: selenium/node-firefox:3.8.1-erbium
|
||||
image: selenium/node-firefox
|
||||
links:
|
||||
- hub
|
||||
environment:
|
||||
|
||||
@ -1,8 +1,13 @@
|
||||
exports.command = function navigateTo (url) {
|
||||
const spinny = 'div.spinny';
|
||||
|
||||
exports.command = function navigateTo (url, expectSpinny = true) {
|
||||
this.url('data:,'); // https://github.com/nightwatchjs/nightwatch/issues/1724
|
||||
this.url(url);
|
||||
|
||||
this.waitForElementVisible('div.spinny');
|
||||
this.waitForElementNotVisible('div.spinny');
|
||||
if (expectSpinny) {
|
||||
this.waitForElementVisible(spinny);
|
||||
this.waitForElementNotVisible(spinny);
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
57
awx/ui/test/e2e/commands/pushFileToWorker.js
Normal file
57
awx/ui/test/e2e/commands/pushFileToWorker.js
Normal file
@ -0,0 +1,57 @@
|
||||
import { basename } from 'path';
|
||||
import { EventEmitter } from 'events';
|
||||
import { inherits } from 'util';
|
||||
|
||||
import archiver from 'archiver';
|
||||
|
||||
function pushFileToWorker (localFilePath, callback) {
|
||||
const name = basename(localFilePath);
|
||||
|
||||
const push = handler => {
|
||||
const archive = archiver('zip');
|
||||
|
||||
const buffers = [];
|
||||
|
||||
archive
|
||||
.on('data', data => buffers.push(data))
|
||||
.on('error', err => { throw err; })
|
||||
.on('finish', () => {
|
||||
const file = Buffer.concat(buffers).toString('base64');
|
||||
|
||||
this.api.session(session => {
|
||||
const params = {
|
||||
path: `/session/${session.sessionId}/file`,
|
||||
method: 'POST',
|
||||
data: { file },
|
||||
};
|
||||
|
||||
this.client.runProtocolAction(params, handler).send();
|
||||
});
|
||||
});
|
||||
|
||||
archive.file(localFilePath, { name });
|
||||
archive.finalize();
|
||||
};
|
||||
|
||||
push(({ status, value }) => {
|
||||
if (status !== 0) {
|
||||
throw new Error(value.message);
|
||||
}
|
||||
|
||||
if (typeof callback === 'function') {
|
||||
callback.call(this, value);
|
||||
}
|
||||
|
||||
this.emit('complete');
|
||||
});
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
function PushFileToWorker () { EventEmitter.call(this); }
|
||||
|
||||
inherits(PushFileToWorker, EventEmitter);
|
||||
|
||||
PushFileToWorker.prototype.command = pushFileToWorker;
|
||||
|
||||
module.exports = PushFileToWorker;
|
||||
@ -10,24 +10,17 @@ import {
|
||||
const session = `e2e-${uuid().substr(0, 8)}`;
|
||||
const store = {};
|
||||
|
||||
const getOrCreate = (endpoint, data, unique = ['name', 'username', 'id']) => {
|
||||
const identifier = Object.keys(data).find(key => unique.includes(key));
|
||||
const getOrCreate = (endpoint, data, unique = ['name']) => {
|
||||
const identifiers = Object.keys(data).filter(key => unique.indexOf(key) > -1);
|
||||
|
||||
if (identifier === undefined) {
|
||||
if (identifiers.length < 1) {
|
||||
throw new Error('A unique key value must be provided.');
|
||||
}
|
||||
|
||||
const identity = data[identifier];
|
||||
const lookup = `${endpoint}/${identifiers.map(key => data[key]).join('-')}`;
|
||||
const params = Object.assign(...identifiers.map(key => ({ [key]: data[key] })));
|
||||
|
||||
store[endpoint] = store[endpoint] || {};
|
||||
|
||||
if (store[endpoint][identity]) {
|
||||
return store[endpoint][identity].then(created => created.data);
|
||||
}
|
||||
|
||||
const query = { params: { [identifier]: identity } };
|
||||
|
||||
store[endpoint][identity] = get(endpoint, query)
|
||||
store[lookup] = store[lookup] || get(endpoint, { params })
|
||||
.then(res => {
|
||||
if (res.data.results.length > 1) {
|
||||
return Promise.reject(new Error('More than one matching result.'));
|
||||
@ -44,7 +37,7 @@ const getOrCreate = (endpoint, data, unique = ['name', 'username', 'id']) => {
|
||||
return Promise.reject(new Error(`unexpected response: ${res}`));
|
||||
});
|
||||
|
||||
return store[endpoint][identity].then(created => created.data);
|
||||
return store[lookup].then(created => created.data);
|
||||
};
|
||||
|
||||
const getOrganization = (namespace = session) => getOrCreate('/organizations/', {
|
||||
@ -57,7 +50,12 @@ const getInventory = (namespace = session) => getOrganization(namespace)
|
||||
name: `${namespace}-inventory`,
|
||||
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)
|
||||
.then(inventory => getOrCreate('/hosts/', {
|
||||
@ -65,7 +63,7 @@ const getHost = (namespace = session) => getInventory(namespace)
|
||||
description: namespace,
|
||||
inventory: inventory.id,
|
||||
variables: JSON.stringify({ ansible_connection: 'local' }),
|
||||
}));
|
||||
}, ['name', 'inventory']));
|
||||
|
||||
const getInventoryScript = (namespace = session) => getOrganization(namespace)
|
||||
.then(organization => getOrCreate('/inventory_scripts/', {
|
||||
@ -265,8 +263,8 @@ const getWorkflowTemplate = (namespace = session) => {
|
||||
];
|
||||
|
||||
const createSuccessNodes = ([projectNode, jobNode, sourceNode]) => Promise.all([
|
||||
getOrCreate(projectNode.related.success_nodes, { id: jobNode.id }),
|
||||
getOrCreate(jobNode.related.success_nodes, { id: sourceNode.id }),
|
||||
getOrCreate(projectNode.related.success_nodes, { id: jobNode.id }, ['id']),
|
||||
getOrCreate(jobNode.related.success_nodes, { id: sourceNode.id }, ['id']),
|
||||
]);
|
||||
|
||||
return Promise.all(nodes)
|
||||
@ -287,7 +285,7 @@ const getAuditor = (namespace = session) => getOrganization(namespace)
|
||||
is_superuser: false,
|
||||
is_system_auditor: true,
|
||||
password: AWX_E2E_PASSWORD
|
||||
}));
|
||||
}, ['username']));
|
||||
|
||||
const getUser = (namespace = session) => getOrganization(namespace)
|
||||
.then(organization => getOrCreate('/users/', {
|
||||
@ -299,7 +297,7 @@ const getUser = (namespace = session) => getOrganization(namespace)
|
||||
is_superuser: false,
|
||||
is_system_auditor: false,
|
||||
password: AWX_E2E_PASSWORD
|
||||
}));
|
||||
}, ['username']));
|
||||
|
||||
const getJobTemplateAdmin = (namespace = session) => {
|
||||
const rolePromise = getJobTemplate(namespace)
|
||||
@ -315,7 +313,7 @@ const getJobTemplateAdmin = (namespace = session) => {
|
||||
is_superuser: false,
|
||||
is_system_auditor: false,
|
||||
password: AWX_E2E_PASSWORD
|
||||
}));
|
||||
}, ['username']));
|
||||
|
||||
const assignRolePromise = Promise.all([userPromise, rolePromise])
|
||||
.then(([user, role]) => post(`/api/v2/roles/${role.id}/users/`, { id: user.id }));
|
||||
@ -338,7 +336,7 @@ const getProjectAdmin = (namespace = session) => {
|
||||
is_superuser: false,
|
||||
is_system_auditor: false,
|
||||
password: AWX_E2E_PASSWORD
|
||||
}));
|
||||
}, ['username']));
|
||||
|
||||
const assignRolePromise = Promise.all([userPromise, rolePromise])
|
||||
.then(([user, role]) => post(`/api/v2/roles/${role.id}/users/`, { id: user.id }));
|
||||
|
||||
@ -2,6 +2,12 @@ module.exports = {
|
||||
url () {
|
||||
return `${this.api.globals.launch_url}/#/activity_stream`;
|
||||
},
|
||||
commands: [{
|
||||
load () {
|
||||
this.api.url('data:,'); // https://github.com/nightwatchjs/nightwatch/issues/1724
|
||||
return this.navigate();
|
||||
},
|
||||
}],
|
||||
elements: {
|
||||
title: '.List-titleText',
|
||||
subtitle: '.List-titleLockup',
|
||||
|
||||
@ -52,6 +52,12 @@ module.exports = {
|
||||
url () {
|
||||
return `${this.api.globals.launch_url}/#/credential_types`;
|
||||
},
|
||||
commands: [{
|
||||
load () {
|
||||
this.api.url('data:,'); // https://github.com/nightwatchjs/nightwatch/issues/1724
|
||||
return this.navigate();
|
||||
},
|
||||
}],
|
||||
sections: {
|
||||
header,
|
||||
breadcrumb,
|
||||
|
||||
@ -216,6 +216,12 @@ module.exports = {
|
||||
url () {
|
||||
return `${this.api.globals.launch_url}/#/credentials`;
|
||||
},
|
||||
commands: [{
|
||||
load () {
|
||||
this.api.url('data:,'); // https://github.com/nightwatchjs/nightwatch/issues/1724
|
||||
return this.navigate();
|
||||
},
|
||||
}],
|
||||
sections: {
|
||||
header,
|
||||
navigation,
|
||||
|
||||
@ -116,6 +116,10 @@ module.exports = {
|
||||
save: 'button[class*="Form-saveButton"]'
|
||||
},
|
||||
commands: [{
|
||||
load () {
|
||||
this.api.url('data:,'); // https://github.com/nightwatchjs/nightwatch/issues/1724
|
||||
return this.navigate();
|
||||
},
|
||||
selectAdd (name) {
|
||||
this.api.waitForElementVisible('button span[class="List-dropdownCarat"]');
|
||||
this.expect.element('button span[class="List-dropdownCarat"]').enabled;
|
||||
|
||||
@ -24,6 +24,12 @@ module.exports = {
|
||||
url () {
|
||||
return `${this.api.globals.launch_url}/#/inventory_scripts`;
|
||||
},
|
||||
commands: [{
|
||||
load () {
|
||||
this.api.url('data:,'); // https://github.com/nightwatchjs/nightwatch/issues/1724
|
||||
return this.navigate();
|
||||
},
|
||||
}],
|
||||
sections: {
|
||||
header,
|
||||
navigation,
|
||||
|
||||
@ -6,5 +6,10 @@ module.exports = {
|
||||
},
|
||||
sections: {}, // TODO: Fill this out
|
||||
elements: {}, // TODO: Fill this out
|
||||
commands: [], // TODO: Fill this out as needed
|
||||
commands: [{
|
||||
load () {
|
||||
this.api.url('data:,'); // https://github.com/nightwatchjs/nightwatch/issues/1724
|
||||
return this.navigate();
|
||||
},
|
||||
}],
|
||||
};
|
||||
|
||||
@ -2,6 +2,12 @@ module.exports = {
|
||||
url () {
|
||||
return `${this.api.globals.launch_url}/#/login`;
|
||||
},
|
||||
commands: [{
|
||||
load () {
|
||||
this.api.url('data:,'); // https://github.com/nightwatchjs/nightwatch/issues/1724
|
||||
return this.navigate();
|
||||
},
|
||||
}],
|
||||
elements: {
|
||||
username: '#login-username',
|
||||
password: '#login-password',
|
||||
|
||||
@ -29,6 +29,12 @@ module.exports = {
|
||||
url () {
|
||||
return `${this.api.globals.launch_url}/#/notification_templates`;
|
||||
},
|
||||
commands: [{
|
||||
load () {
|
||||
this.api.url('data:,'); // https://github.com/nightwatchjs/nightwatch/issues/1724
|
||||
return this.navigate();
|
||||
},
|
||||
}],
|
||||
sections: {
|
||||
header,
|
||||
navigation,
|
||||
|
||||
@ -26,6 +26,12 @@ module.exports = {
|
||||
url () {
|
||||
return `${this.api.globals.launch_url}/#/organizations`;
|
||||
},
|
||||
commands: [{
|
||||
load () {
|
||||
this.api.url('data:,'); // https://github.com/nightwatchjs/nightwatch/issues/1724
|
||||
return this.navigate();
|
||||
},
|
||||
}],
|
||||
sections: {
|
||||
header,
|
||||
navigation,
|
||||
|
||||
@ -25,6 +25,12 @@ module.exports = {
|
||||
url () {
|
||||
return `${this.api.globals.launch_url}/#/projects`;
|
||||
},
|
||||
commands: [{
|
||||
load () {
|
||||
this.api.url('data:,'); // https://github.com/nightwatchjs/nightwatch/issues/1724
|
||||
return this.navigate();
|
||||
},
|
||||
}],
|
||||
sections: {
|
||||
header,
|
||||
navigation,
|
||||
|
||||
@ -23,6 +23,12 @@ module.exports = {
|
||||
url () {
|
||||
return `${this.api.globals.launch_url}/#/teams`;
|
||||
},
|
||||
commands: [{
|
||||
load () {
|
||||
this.api.url('data:,'); // https://github.com/nightwatchjs/nightwatch/issues/1724
|
||||
return this.navigate();
|
||||
},
|
||||
}],
|
||||
sections: {
|
||||
header,
|
||||
navigation,
|
||||
|
||||
@ -116,6 +116,10 @@ module.exports = {
|
||||
save: 'button[class*="Form-saveButton"]'
|
||||
},
|
||||
commands: [{
|
||||
load () {
|
||||
this.api.url('data:,'); // https://github.com/nightwatchjs/nightwatch/issues/1724
|
||||
return this.navigate();
|
||||
},
|
||||
clickWhenEnabled (selector) {
|
||||
this.api.waitForElementVisible(selector);
|
||||
this.expect.element(selector).enabled;
|
||||
|
||||
@ -23,6 +23,12 @@ module.exports = {
|
||||
url () {
|
||||
return `${this.api.globals.launch_url}/#/users`;
|
||||
},
|
||||
commands: [{
|
||||
load () {
|
||||
this.api.url('data:,'); // https://github.com/nightwatchjs/nightwatch/issues/1724
|
||||
return this.navigate();
|
||||
},
|
||||
}],
|
||||
sections: {
|
||||
header,
|
||||
navigation,
|
||||
|
||||
@ -4,7 +4,7 @@ const AWX_E2E_CLUSTER_WORKERS = process.env.AWX_E2E_CLUSTER_WORKERS || 0;
|
||||
const AWX_E2E_PASSWORD = process.env.AWX_E2E_PASSWORD || 'password';
|
||||
const AWX_E2E_URL = process.env.AWX_E2E_URL || 'https://localhost:8043';
|
||||
const AWX_E2E_USERNAME = process.env.AWX_E2E_USERNAME || 'awx-e2e';
|
||||
const AWX_E2E_TIMEOUT_ASYNC = process.env.AWX_E2E_TIMEOUT_ASYNC || 30000;
|
||||
const AWX_E2E_TIMEOUT_ASYNC = process.env.AWX_E2E_TIMEOUT_ASYNC || 90000;
|
||||
const AWX_E2E_TIMEOUT_LONG = process.env.AWX_E2E_TIMEOUT_LONG || 10000;
|
||||
const AWX_E2E_TIMEOUT_MEDIUM = process.env.AWX_E2E_TIMEOUT_MEDIUM || 5000;
|
||||
const AWX_E2E_TIMEOUT_SHORT = process.env.AWX_E2E_TIMEOUT_SHORT || 1000;
|
||||
|
||||
@ -58,7 +58,8 @@ module.exports = {
|
||||
|
||||
projects.section.list.waitForElementVisible('@add');
|
||||
projects.section.list.expect.element('@add').enabled;
|
||||
projects.section.list.click('@add');
|
||||
|
||||
client.pause(1000); projects.section.list.click('@add');
|
||||
|
||||
projects.waitForElementVisible('label[for="name"] + div input');
|
||||
projects.waitForElementVisible('label[for="organization"] + div input');
|
||||
@ -269,6 +270,7 @@ module.exports = {
|
||||
templates.waitForElementVisible('smart-search input');
|
||||
templates.expect.element('smart-search input').enabled;
|
||||
|
||||
client.pause(1000).waitForElementNotVisible('div.spinny');
|
||||
templates.sendKeys('smart-search input', `${TEMPLATE_NAME}${client.Keys.ENTER}`);
|
||||
templates.waitForElementVisible('div.spinny');
|
||||
templates.waitForElementNotVisible('div.spinny');
|
||||
|
||||
@ -24,13 +24,6 @@ let users;
|
||||
let inventories;
|
||||
let teams;
|
||||
|
||||
function navigateAndWaitForSpinner (client, url) {
|
||||
client
|
||||
.url(url)
|
||||
.waitForElementVisible('div.spinny')
|
||||
.waitForElementNotVisible('div.spinny');
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
before: (client, done) => {
|
||||
const promises = [
|
||||
@ -68,7 +61,9 @@ module.exports = {
|
||||
});
|
||||
},
|
||||
'verify an auditor\'s credentials inputs are read-only': client => {
|
||||
navigateAndWaitForSpinner(client, `${credentials.url()}/${data.adminAWSCredential.id}/`);
|
||||
const url = `${credentials.url()}/${data.adminAWSCredential.id}/`;
|
||||
|
||||
client.navigateTo(url);
|
||||
|
||||
credentials.section.edit
|
||||
.expect.element('@title').text.contain(data.adminAWSCredential.name);
|
||||
@ -76,7 +71,9 @@ module.exports = {
|
||||
credentials.section.edit.section.details.checkAllFieldsDisabled();
|
||||
},
|
||||
'verify an auditor\'s inventory scripts inputs are read-only': client => {
|
||||
navigateAndWaitForSpinner(client, `${inventoryScripts.url()}/${data.inventoryScript.id}/`);
|
||||
const url = `${inventoryScripts.url()}/${data.inventoryScript.id}/`;
|
||||
|
||||
client.navigateTo(url);
|
||||
|
||||
inventoryScripts.section.edit
|
||||
.expect.element('@title').text.contain(data.inventoryScript.name);
|
||||
@ -92,7 +89,7 @@ module.exports = {
|
||||
//
|
||||
// 'verify an auditor\'s job template inputs are read-only': function (client) {
|
||||
// const url = `${templates.url()}/job_template/${data.jobTemplate.id}/`;
|
||||
// navigateAndWaitForSpinner(client, url);
|
||||
// client.navigateTo(url)''
|
||||
//
|
||||
// templates.section.editJobTemplate
|
||||
// .expect.element('@title').text.contain(data.jobTemplate.name);
|
||||
@ -103,7 +100,9 @@ module.exports = {
|
||||
// templates.expect.element('@save').to.not.be.visible;
|
||||
// },
|
||||
'verify an auditor\'s notification templates inputs are read-only': client => {
|
||||
navigateAndWaitForSpinner(client, `${notificationTemplates.url()}/${data.notificationTemplate.id}/`);
|
||||
const url = `${notificationTemplates.url()}/${data.notificationTemplate.id}/`;
|
||||
|
||||
client.navigateTo(url);
|
||||
|
||||
notificationTemplates.section.edit
|
||||
.expect.element('@title').text.contain(data.notificationTemplate.name);
|
||||
@ -114,7 +113,9 @@ module.exports = {
|
||||
notificationTemplates.expect.element('@save').to.not.be.visible;
|
||||
},
|
||||
'verify an auditor\'s organizations inputs are read-only': client => {
|
||||
navigateAndWaitForSpinner(client, `${organizations.url()}/${data.organization.id}/`);
|
||||
const url = `${organizations.url()}/${data.organization.id}/`;
|
||||
|
||||
client.navigateTo(url);
|
||||
|
||||
organizations.section.edit
|
||||
.expect.element('@title').text.contain(data.organization.name);
|
||||
@ -125,7 +126,9 @@ module.exports = {
|
||||
organizations.expect.element('@save').to.not.be.visible;
|
||||
},
|
||||
'verify an auditor\'s smart inventory inputs are read-only': client => {
|
||||
navigateAndWaitForSpinner(client, `${inventories.url()}/smart/${data.smartInventory.id}/`);
|
||||
const url = `${inventories.url()}/smart/${data.smartInventory.id}/`;
|
||||
|
||||
client.navigateTo(url);
|
||||
|
||||
inventories.section.editSmartInventory
|
||||
.expect.element('@title').text.contain(data.smartInventory.name);
|
||||
@ -136,7 +139,9 @@ module.exports = {
|
||||
inventories.expect.element('@save').to.not.be.visible;
|
||||
},
|
||||
'verify an auditor\'s project inputs are read-only': client => {
|
||||
navigateAndWaitForSpinner(client, `${projects.url()}/${data.project.id}/`);
|
||||
const url = `${projects.url()}/${data.project.id}/`;
|
||||
|
||||
client.navigateTo(url);
|
||||
|
||||
projects.section.edit
|
||||
.expect.element('@title').text.contain(data.project.name);
|
||||
@ -147,7 +152,9 @@ module.exports = {
|
||||
projects.expect.element('@save').to.not.be.visible;
|
||||
},
|
||||
'verify an auditor\'s standard inventory inputs are read-only': client => {
|
||||
navigateAndWaitForSpinner(client, `${inventories.url()}/inventory/${data.inventory.id}/`);
|
||||
const url = `${inventories.url()}/inventory/${data.inventory.id}/`;
|
||||
|
||||
client.navigateTo(url);
|
||||
|
||||
inventories.section.editStandardInventory
|
||||
.expect.element('@title').text.contain(data.inventory.name);
|
||||
@ -159,7 +166,9 @@ module.exports = {
|
||||
inventories.expect.element('@save').to.not.be.visible;
|
||||
},
|
||||
'verify an auditor\'s teams inputs are read-only': client => {
|
||||
navigateAndWaitForSpinner(client, `${teams.url()}/${data.team.id}/`);
|
||||
const url = `${teams.url()}/${data.team.id}/`;
|
||||
|
||||
client.navigateTo(url);
|
||||
|
||||
teams.section.edit
|
||||
.expect.element('@title').text.contain(data.team.name);
|
||||
@ -170,7 +179,9 @@ module.exports = {
|
||||
teams.expect.element('@save').to.not.be.visible;
|
||||
},
|
||||
'verify an auditor\'s user inputs are read-only': client => {
|
||||
navigateAndWaitForSpinner(client, `${users.url()}/${data.user.id}/`);
|
||||
const url = `${users.url()}/${data.user.id}/`;
|
||||
|
||||
client.navigateTo(url);
|
||||
|
||||
users.section.edit
|
||||
.expect.element('@title').text.contain(data.user.username);
|
||||
|
||||
@ -5,10 +5,7 @@ module.exports = {
|
||||
client.login();
|
||||
client.waitForAngular();
|
||||
|
||||
credentialTypes
|
||||
.navigate(`${credentialTypes.url()}/add/`)
|
||||
.waitForElementVisible('div.spinny')
|
||||
.waitForElementNotVisible('div.spinny');
|
||||
credentialTypes.navigateTo(`${credentialTypes.url()}/add/`);
|
||||
|
||||
credentialTypes.section.add
|
||||
.waitForElementVisible('@title', done);
|
||||
|
||||
@ -64,7 +64,9 @@ module.exports = {
|
||||
const { details } = credentials.section.add.section;
|
||||
const { gce } = details.section;
|
||||
|
||||
gce.section.serviceAccountFile.setValue('form input[type="file"]', GCE_SERVICE_ACCOUNT_FILE);
|
||||
client.pushFileToWorker(GCE_SERVICE_ACCOUNT_FILE, file => {
|
||||
gce.section.serviceAccountFile.setValue('form input[type="file"]', file);
|
||||
});
|
||||
|
||||
gce.expect.element('@email').not.enabled;
|
||||
gce.expect.element('@sshKeyData').not.enabled;
|
||||
@ -100,7 +102,9 @@ module.exports = {
|
||||
const { details } = credentials.section.add.section;
|
||||
const { gce } = details.section;
|
||||
|
||||
gce.section.serviceAccountFile.setValue('form input[type="file"]', GCE_SERVICE_ACCOUNT_FILE_MISSING);
|
||||
client.pushFileToWorker(GCE_SERVICE_ACCOUNT_FILE_MISSING, file => {
|
||||
gce.section.serviceAccountFile.setValue('form input[type="file"]', file);
|
||||
});
|
||||
|
||||
gce.expect.element('@email').not.enabled;
|
||||
gce.expect.element('@sshKeyData').not.enabled;
|
||||
@ -142,7 +146,9 @@ module.exports = {
|
||||
const { details } = credentials.section.add.section;
|
||||
const { gce } = details.section;
|
||||
|
||||
gce.section.serviceAccountFile.setValue('form input[type="file"]', GCE_SERVICE_ACCOUNT_FILE_INVALID);
|
||||
client.pushFileToWorker(GCE_SERVICE_ACCOUNT_FILE_INVALID, file => {
|
||||
gce.section.serviceAccountFile.setValue('form input[type="file"]', file);
|
||||
});
|
||||
|
||||
gce.expect.element('@email').not.enabled;
|
||||
gce.expect.element('@sshKeyData').not.enabled;
|
||||
@ -184,7 +190,9 @@ module.exports = {
|
||||
const add = credentials.section.add.section.details;
|
||||
const edit = credentials.section.edit.section.details;
|
||||
|
||||
add.section.gce.section.serviceAccountFile.setValue('form input[type="file"]', GCE_SERVICE_ACCOUNT_FILE);
|
||||
client.pushFileToWorker(GCE_SERVICE_ACCOUNT_FILE, file => {
|
||||
add.section.gce.section.serviceAccountFile.setValue('form input[type="file"]', file);
|
||||
});
|
||||
|
||||
add.section.gce.expect.element('@email').not.enabled;
|
||||
add.section.gce.expect.element('@sshKeyData').not.enabled;
|
||||
@ -224,7 +232,9 @@ module.exports = {
|
||||
gce.section.project.expect.element('@error').not.present;
|
||||
gce.section.serviceAccountFile.expect.element('@error').not.present;
|
||||
|
||||
gce.section.serviceAccountFile.setValue('form input[type="file"]', GCE_SERVICE_ACCOUNT_FILE_ALT);
|
||||
client.pushFileToWorker(GCE_SERVICE_ACCOUNT_FILE_ALT, file => {
|
||||
gce.section.serviceAccountFile.setValue('form input[type="file"]', file);
|
||||
});
|
||||
|
||||
gce.expect.element('@serviceAccountFile').enabled;
|
||||
|
||||
|
||||
@ -166,18 +166,6 @@ module.exports = {
|
||||
|
||||
credentials.section.edit.expect.section('@details').visible;
|
||||
},
|
||||
'credential is searchable after saving': client => {
|
||||
const credentials = client.page.credentials();
|
||||
const row = '#credentials_table tbody tr';
|
||||
|
||||
credentials.section.list.section.search
|
||||
.waitForElementVisible('@input', AWX_E2E_TIMEOUT_LONG)
|
||||
.setValue('@input', `name:${store.credential.name}`)
|
||||
.click('@searchButton');
|
||||
|
||||
credentials.waitForElementNotPresent(`${row}:nth-of-type(2)`);
|
||||
credentials.expect.element(row).text.contain(store.credential.name);
|
||||
},
|
||||
'change the password after saving': client => {
|
||||
const credentials = client.page.credentials();
|
||||
const { edit } = credentials.section;
|
||||
@ -190,6 +178,7 @@ module.exports = {
|
||||
machine.expect.element('@password').not.enabled;
|
||||
|
||||
machine.section.password.click('@replace');
|
||||
|
||||
machine.section.password.expect.element('@replace').not.present;
|
||||
machine.section.password.expect.element('@revert').visible;
|
||||
|
||||
@ -201,7 +190,19 @@ module.exports = {
|
||||
credentials
|
||||
.waitForElementVisible('div.spinny')
|
||||
.waitForElementNotVisible('div.spinny');
|
||||
},
|
||||
'credential is searchable after saving': client => {
|
||||
const credentials = client.page.credentials();
|
||||
const row = '#credentials_table tbody tr';
|
||||
|
||||
credentials.section.list.section.search
|
||||
.waitForElementVisible('@input', AWX_E2E_TIMEOUT_LONG)
|
||||
.setValue('@input', `name:${store.credential.name}`)
|
||||
.click('@searchButton');
|
||||
|
||||
credentials.waitForElementNotPresent(`${row}:nth-of-type(2)`);
|
||||
credentials.expect.element(row).text.contain(store.credential.name);
|
||||
|
||||
client.end();
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
@ -16,7 +16,7 @@ module.exports = {
|
||||
client.login();
|
||||
client.waitForAngular();
|
||||
|
||||
credentials.navigate();
|
||||
credentials.load();
|
||||
credentials.waitForElementVisible('div.spinny');
|
||||
credentials.waitForElementNotVisible('div.spinny');
|
||||
|
||||
|
||||
@ -1,25 +1,32 @@
|
||||
import { range } from 'lodash';
|
||||
|
||||
import { getOrganization } from '../fixtures';
|
||||
|
||||
module.exports = {
|
||||
before: (client, done) => {
|
||||
const credentials = client.page.credentials();
|
||||
const { details } = credentials.section.add.section;
|
||||
const resources = range(100).map(n => getOrganization(`test-lookup-${n}`));
|
||||
|
||||
client.login();
|
||||
client.waitForAngular();
|
||||
Promise.all(resources)
|
||||
.then(() => {
|
||||
const credentials = client.page.credentials();
|
||||
const { details } = credentials.section.add.section;
|
||||
|
||||
credentials.section.navigation
|
||||
.waitForElementVisible('@credentials')
|
||||
.click('@credentials');
|
||||
client.login();
|
||||
client.waitForAngular();
|
||||
|
||||
credentials
|
||||
.waitForElementVisible('div.spinny')
|
||||
.waitForElementNotVisible('div.spinny');
|
||||
credentials.section.navigation.waitForElementVisible('@credentials');
|
||||
credentials.section.navigation.click('@credentials');
|
||||
|
||||
credentials.section.list
|
||||
.waitForElementVisible('@add')
|
||||
.click('@add');
|
||||
credentials.waitForElementVisible('div.spinny');
|
||||
credentials.waitForElementNotVisible('div.spinny');
|
||||
|
||||
details
|
||||
.waitForElementVisible('@save', done);
|
||||
credentials.section.list.waitForElementVisible('@add');
|
||||
credentials.section.list.click('@add');
|
||||
|
||||
details.waitForElementVisible('@save');
|
||||
|
||||
done();
|
||||
});
|
||||
},
|
||||
'open the lookup modal': client => {
|
||||
const credentials = client.page.credentials();
|
||||
|
||||
@ -6,7 +6,7 @@ module.exports = {
|
||||
client.waitForAngular();
|
||||
|
||||
credentials
|
||||
.navigate()
|
||||
.load()
|
||||
.waitForElementVisible('div.spinny')
|
||||
.waitForElementNotVisible('div.spinny', done);
|
||||
},
|
||||
|
||||
@ -10,7 +10,7 @@ module.exports = {
|
||||
client.waitForAngular();
|
||||
|
||||
credentials
|
||||
.navigate()
|
||||
.load()
|
||||
.waitForElementVisible('div.spinny')
|
||||
.waitForElementNotVisible('div.spinny');
|
||||
|
||||
|
||||
@ -16,7 +16,7 @@ module.exports = {
|
||||
client.login();
|
||||
client.waitForAngular();
|
||||
|
||||
inventories.navigate();
|
||||
inventories.load();
|
||||
inventories.waitForElementVisible('div.spinny');
|
||||
inventories.waitForElementNotVisible('div.spinny');
|
||||
|
||||
|
||||
@ -16,7 +16,7 @@ module.exports = {
|
||||
client.login();
|
||||
client.waitForAngular();
|
||||
|
||||
inventoryScripts.navigate();
|
||||
inventoryScripts.load();
|
||||
inventoryScripts.waitForElementVisible('div.spinny');
|
||||
inventoryScripts.waitForElementNotVisible('div.spinny');
|
||||
|
||||
|
||||
@ -16,7 +16,7 @@ module.exports = {
|
||||
client.login();
|
||||
client.waitForAngular();
|
||||
|
||||
notifications.navigate();
|
||||
notifications.load();
|
||||
notifications.waitForElementVisible('div.spinny');
|
||||
notifications.waitForElementNotVisible('div.spinny');
|
||||
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
import { getProject } from '../fixtures';
|
||||
import { getUpdatedProject } from '../fixtures';
|
||||
|
||||
const data = {};
|
||||
|
||||
module.exports = {
|
||||
before: (client, done) => {
|
||||
getProject('test-actions')
|
||||
getUpdatedProject('test-actions')
|
||||
.then(obj => { data.project = obj; })
|
||||
.then(done);
|
||||
},
|
||||
@ -16,7 +16,7 @@ module.exports = {
|
||||
client.login();
|
||||
client.waitForAngular();
|
||||
|
||||
projects.navigate();
|
||||
projects.load();
|
||||
projects.waitForElementVisible('div.spinny');
|
||||
projects.waitForElementNotVisible('div.spinny');
|
||||
|
||||
|
||||
@ -65,7 +65,7 @@ module.exports = {
|
||||
client.login();
|
||||
client.waitForAngular();
|
||||
|
||||
templates.navigate();
|
||||
templates.load();
|
||||
templates.waitForElementVisible('div.spinny');
|
||||
templates.waitForElementNotVisible('div.spinny');
|
||||
|
||||
@ -120,7 +120,7 @@ module.exports = {
|
||||
client.login();
|
||||
client.waitForAngular();
|
||||
|
||||
templates.navigate();
|
||||
templates.load();
|
||||
templates.waitForElementVisible('div.spinny');
|
||||
templates.waitForElementNotVisible('div.spinny');
|
||||
|
||||
@ -170,7 +170,7 @@ module.exports = {
|
||||
client.login(data.user.username);
|
||||
client.waitForAngular();
|
||||
|
||||
templates.navigate();
|
||||
templates.load();
|
||||
templates.waitForElementVisible('div.spinny');
|
||||
templates.waitForElementNotVisible('div.spinny');
|
||||
|
||||
|
||||
@ -30,7 +30,7 @@ module.exports = {
|
||||
client.login();
|
||||
client.waitForAngular();
|
||||
|
||||
templates.navigate();
|
||||
templates.load();
|
||||
templates.waitForElementVisible('div.spinny');
|
||||
templates.waitForElementNotVisible('div.spinny');
|
||||
|
||||
@ -70,7 +70,7 @@ module.exports = {
|
||||
client.login();
|
||||
client.waitForAngular();
|
||||
|
||||
templates.navigate();
|
||||
templates.load();
|
||||
templates.waitForElementVisible('div.spinny');
|
||||
templates.waitForElementNotVisible('div.spinny');
|
||||
|
||||
|
||||
@ -40,7 +40,7 @@ module.exports = {
|
||||
getTeam(namespace).then(obj => { data.team = obj; }),
|
||||
getProjectAdmin(namespace).then(obj => { data.user = obj; }),
|
||||
getNotificationTemplate(namespace).then(obj => { data.notification = obj; }),
|
||||
getJob(namespaceShort).then(obj => { data.job = obj; }),
|
||||
getJob(namespace).then(obj => { data.job = obj; }),
|
||||
];
|
||||
|
||||
Promise.all(resources)
|
||||
@ -58,7 +58,6 @@ module.exports = {
|
||||
|
||||
urls.organization = `${pages.organizations.url()}/${data.organization.id}`;
|
||||
urls.inventory = `${pages.inventories.url()}/inventory/${data.inventory.id}`;
|
||||
urls.inventoryHosts = `${urls.inventory}/hosts`;
|
||||
urls.inventoryScript = `${pages.inventoryScripts.url()}/${data.inventoryScript.id}`;
|
||||
urls.inventorySource = `${urls.inventory}/inventory_sources/edit/${data.inventorySource.id}`;
|
||||
urls.sourceSchedule = `${urls.inventorySource}/schedules/${data.sourceSchedule.id}`;
|
||||
@ -72,6 +71,7 @@ module.exports = {
|
||||
urls.notification = `${pages.notificationTemplates.url()}/${data.notification.id}`;
|
||||
urls.jobs = `${pages.jobs.url()}`;
|
||||
urls.jobsSchedules = `${pages.jobs.url()}/schedules`;
|
||||
urls.inventoryHosts = `${pages.inventories.url()}/inventory/${data.host.summary_fields.inventory.id}/hosts`;
|
||||
|
||||
client.useCss();
|
||||
client.login();
|
||||
@ -85,7 +85,7 @@ module.exports = {
|
||||
const multiCredentialOpen = 'multi-credential button i[class*="search"]';
|
||||
const multiCredentialExit = 'multi-credential-modal button[class*="exit"]';
|
||||
|
||||
client.url(urls.jobTemplate);
|
||||
client.navigateTo(urls.jobTemplate, false);
|
||||
|
||||
client.expect.element('#job_template_form').visible;
|
||||
client.expect.element('#xss').not.present;
|
||||
@ -371,7 +371,7 @@ module.exports = {
|
||||
client.expect.element('#prompt-header').not.visible;
|
||||
},
|
||||
'check smart inventory form for unsanitized content': client => {
|
||||
client.url(urls.smartInventory);
|
||||
client.navigateTo(urls.smartInventory, false);
|
||||
|
||||
client.expect.element('#smartinventory_form').visible;
|
||||
|
||||
@ -691,6 +691,14 @@ module.exports = {
|
||||
const popOver = `${itemRow} td[class*="active_failures-"] div[class*="popover"]`;
|
||||
|
||||
client.navigateTo(urls.inventoryHosts);
|
||||
client.expect.element('div[class^="Panel"] smart-search').visible;
|
||||
client.expect.element('div[class^="Panel"] smart-search input').enabled;
|
||||
|
||||
client.sendKeys('div[class^="Panel"] smart-search input', `id:>${data.host.id - 1} id:<${data.host.id + 1}`);
|
||||
client.sendKeys('div[class^="Panel"] smart-search input', client.Keys.ENTER);
|
||||
|
||||
client.expect.element('div.spinny').visible;
|
||||
client.expect.element('div.spinny').not.visible;
|
||||
|
||||
client.click(itemName);
|
||||
client.expect.element(popOver).present;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user