Skip to content

Commit

Permalink
Merge pull request #4444 from elyezer/app-token-e2e
Browse files Browse the repository at this point in the history
  • Loading branch information
2 parents 3441d0c + e7a15d4 commit 9b836ab
Show file tree
Hide file tree
Showing 5 changed files with 170 additions and 16 deletions.
21 changes: 13 additions & 8 deletions awx/ui/test/e2e/fixtures.js
Original file line number Diff line number Diff line change
Expand Up @@ -438,17 +438,22 @@ const getUser = (
// where a user and org both exist, but the user is not in the organization.
// this ensures a new user is always created.
username = `user-${uuid().substr(0, 8)}`,
isSuperuser = false
password = AWX_E2E_PASSWORD,
isSuperuser = false,
isSystemAuditor = false,
email = `email-${uuid().substr(0, 8)}@example.com`,
firstName = `first-name-${uuid().substr(0, 8)}`,
lastName = `last-name-${uuid().substr(0, 8)}`
) => getOrganization(namespace)
.then(organization => getOrCreate(`/organizations/${organization.id}/users/`, {
username: `${username}-${uuid().substr(0, 8)}`,
email,
first_name: firstName,
is_superuser: isSuperuser,
is_system_auditor: isSystemAuditor,
last_name: lastName,
organization: organization.id,
first_name: 'firstname',
last_name: 'lastname',
email: '[email protected]',
is_superuser: `${isSuperuser}`,
is_system_auditor: false,
password: AWX_E2E_PASSWORD
password,
username,
}, ['username']));

/* Retrieves a job template admin, and creates it if it does not exist.
Expand Down
7 changes: 7 additions & 0 deletions awx/ui/test/e2e/objects/applications.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ const addEditElements = {
redirectUris: '#application_redirect_uris_group input',
clientType: '#application_client_type_group select',
save: 'button[type=save]',
tokensTab: 'div.card button.at-Tab:nth-of-type(2)',
};

const authorizationGrantTypeOptions = {
Expand Down Expand Up @@ -131,6 +132,12 @@ module.exports = {
}
})
}
},
tokens: {
selector: 'div.card',
elements: {
list: '.at-List-container',
}
}
},
elements: {
Expand Down
76 changes: 75 additions & 1 deletion awx/ui/test/e2e/objects/users.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,63 @@ module.exports = {
this.expect.element('.List-titleBadge').text.to.contain('1');
this.expect.element(row).text.contain(username);
},
createToken (username, token, callback) {
this.search(username);
const editButton = `${row} i[class*="fa-pencil"]`;
this
.waitForElementVisible(editButton)
.click(editButton);
this.section.tokens
.waitForElementVisible('@tokensTab')
.click('@tokensTab')
.waitForSpinny()
.click('@add');
const { createToken } = this.section;
createToken.waitForElementVisible('@application');
this.expect.element(this.section.breadcrumb.selector).text.to.contain(`USERS ${username} TOKENS CREATE TOKEN`);
if (token.application) {
createToken.setValue('@application', token.application);
}
if (token.description) {
createToken.setValue('@description', token.description);
}
if (token.scope) {
createToken
.click('@scope')
.click(`option[label=${token.scope}]`);
}
createToken.click('@saveButton');
this.waitForSpinny()
.waitForElementVisible('#alert-modal-msg');

const tokenInfo = {
token: null,
refreshToken: null,
expires: null,
};

this.getText(
'#alert-modal-msg .PopupModal:nth-of-type(1) .PopupModal-value',
(result) => { tokenInfo.token = result.value; }
);
this.getText(
'#alert-modal-msg .PopupModal:nth-of-type(2) .PopupModal-value',
(result) => { tokenInfo.refreshToken = result.value; }
);
this.getText(
'#alert-modal-msg .PopupModal:nth-of-type(3) .PopupModal-value',
(result) => { tokenInfo.expires = result.value; }
);

this.findThenClick('#alert_ok_btn', 'css')
.waitForElementNotVisible('#alert-modal-msg');

this.api.perform(() => {
if (typeof callback === 'function') {
callback.call(this.api, tokenInfo);
}
});
},
}],
sections: {
header,
Expand Down Expand Up @@ -134,7 +191,24 @@ module.exports = {
}
})
}
}
},
tokens: {
selector: 'div[ui-view="form"]',
elements: {
add: '#button-add',
tokensTab: '#tokens_tab',
},
},
createToken: {
selector: 'div[ui-view="preFormView"]',
elements: {
application: 'input[tabindex="1"]',
description: 'input[tabindex="2"]',
scope: 'select[tabindex="3"]',
cancelButton: 'button[type="cancel"]',
saveButton: 'button[type="save"]',
}
},
},
elements: {
cancel: 'button[class*="Form-cancelButton"]',
Expand Down
77 changes: 74 additions & 3 deletions awx/ui/test/e2e/tests/test-applications.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
/* Tests for applications. */
import uuid from 'uuid';
import { getOrganization } from '../fixtures';
import {
getOrganization,
getUser
} from '../fixtures';

const row = '.at-List-container .at-Row';
const editLink = `${row} a.ng-binding`;
const testID = uuid().substr(0, 8);
const namespace = 'test-applications';

Expand All @@ -17,13 +21,26 @@ const store = {
redirectUris: `https://example.com/${testID}/`,
// clientType: `client-type-${testID}`,
},
adminUser: {
username: `admin-${testID}`,
password: `admin-${testID}`,
isSuperuser: true,
},
};

let data;

module.exports = {
before: (client, done) => {
const resources = [getOrganization(namespace)];
const resources = [
getOrganization(store.organization.name),
getUser(
namespace,
store.adminUser.username,
store.adminUser.password,
store.adminUser.isSuperuser
),
];
Promise.all(resources)
.then(([org]) => {
data = { org };
Expand Down Expand Up @@ -53,7 +70,6 @@ module.exports = {
applications.load();
client.waitForSpinny();
applications.search(store.application.name);
const editLink = `${row} a.ng-binding`;
client
.waitForElementVisible(editLink)
.expect.element(editLink).text.to.equal(store.application.name);
Expand All @@ -74,6 +90,61 @@ module.exports = {
.waitForElementVisible('@description')
.expect.element('@description').value.to.equal(store.application.description);
},
'add a read scoped application token': client => {
client.logout();
client.login(store.adminUser.username, store.adminUser.password);

// Given the application created on the previous test
const token = {
application: store.application.name,
description: `Read scoped token for ${store.application.name}`,
scope: 'Read',
};
const users = client.page.users();
users.load();
client.waitForSpinny();
users.createToken(store.adminUser.username, token, (tokenInfo) => {
const applications = client.page.applications();
applications.load();
client.waitForSpinny();
applications.search(store.application.name);
client.findThenClick(editLink, 'css');
applications.section.edit
.waitForElementVisible('@tokensTab')
.click('@tokensTab')
.waitForSpinny();
// FIXME: Search is not properly working, update this when it is working.
applications.section.tokens.expect.element('@list').text.to.contain(`${store.adminUser.username}\n${token.description}\nEXPIRATION ${tokenInfo.expires}`);
});
},
'add a write scoped application token': client => {
// Given the application created on the previous test
const token = {
application: store.application.name,
description: `Write scoped token for ${store.application.name}`,
scope: 'Write',
};

const users = client.page.users();
users.load();
client.waitForSpinny();
users.createToken(store.adminUser.username, token, (tokenInfo) => {
const applications = client.page.applications();
applications.load();
client.waitForSpinny();
applications.search(store.application.name);
client.findThenClick(editLink, 'css');
applications.section.edit
.waitForElementVisible('@tokensTab')
.click('@tokensTab')
.waitForSpinny();
// FIXME: Search is not properly working, update this when it is working.
applications.section.tokens.expect.element('@list').text.to.contain(`${store.adminUser.username}\n${token.description}\nEXPIRATION ${tokenInfo.expires}`);
});

client.logout();
client.login();
},
'delete an application': client => {
// Given the application created on the create application test
const applications = client.page.applications();
Expand Down
5 changes: 1 addition & 4 deletions awx/ui/test/e2e/tests/test-users-crud.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,15 +54,12 @@ module.exports = {
});
const resources = [
getOrganization(store.organization.name),
getAuditor(store.auditor.username),
getUser(store.user.username),
getUser(store.admin.username, true)
];

Promise.all(resources)
.then(([organization, auditor, user, admin]) => {
store.organization.name = `${store.organization.name}-organization`;
data = { organization, auditor, user, admin };
data = { organization };
done();
});
client.login();
Expand Down

0 comments on commit 9b836ab

Please sign in to comment.