diff --git a/awx/ui/test/e2e/fixtures.js b/awx/ui/test/e2e/fixtures.js index a0f886e074..a0478ddac5 100644 --- a/awx/ui/test/e2e/fixtures.js +++ b/awx/ui/test/e2e/fixtures.js @@ -282,7 +282,7 @@ const getJobTemplateSchedule = (namespace = session) => getJobTemplate(namespace .then(template => getOrCreate(template.related.schedules, { name: `${template.name}-schedule`, description: namespace, - rrule: 'DTSTART:20171104T040000Z RRULE:FREQ=DAILY;INTERVAL=1;COUNT=1' + rrule: 'DTSTART:20351104T040000Z RRULE:FREQ=DAILY;INTERVAL=1;COUNT=1' })); module.exports = { diff --git a/awx/ui/test/e2e/objects/jobs.js b/awx/ui/test/e2e/objects/jobs.js new file mode 100644 index 0000000000..81bd3d432c --- /dev/null +++ b/awx/ui/test/e2e/objects/jobs.js @@ -0,0 +1,21 @@ +import _ from 'lodash'; + +import actions from './sections/actions'; +import breadcrumb from './sections/breadcrumb'; +import createFormSection from './sections/createFormSection'; +import createTableSection from './sections/createTableSection'; +import header from './sections/header'; +import lookupModal from './sections/lookupModal'; +import navigation from './sections/navigation'; +import pagination from './sections/pagination'; +import permissions from './sections/permissions'; +import search from './sections/search'; + +module.exports = { + url () { + return `${this.api.globals.launch_url}/#/jobs`; + }, + sections: {}, // TODO: Fill this out + elements: {}, // TODO: Fill this out + commands: [], // TODO: Fill this out as needed +}; diff --git a/awx/ui/test/e2e/tests/test-xss.js b/awx/ui/test/e2e/tests/test-xss.js index 7888824691..b5c80afe31 100644 --- a/awx/ui/test/e2e/tests/test-xss.js +++ b/awx/ui/test/e2e/tests/test-xss.js @@ -12,6 +12,7 @@ import { getSmartInventory, getTeam, getUpdatedProject, + getJobs, } from '../fixtures'; const data = {}; @@ -49,6 +50,7 @@ module.exports = { pages.teams = client.page.teams(); pages.users = client.page.users(); pages.notificationTemplates = client.page.notificationTemplates(); + pages.jobs = client.page.jobs(); urls.organization = `${pages.organizations.url()}/${data.organization.id}`; urls.inventory = `${pages.inventories.url()}/inventory/${data.inventory.id}`; @@ -63,6 +65,8 @@ module.exports = { urls.team = `${pages.teams.url()}/${data.team.id}`; urls.user = `${pages.users.url()}/${data.user.id}`; urls.notification = `${pages.notificationTemplates.url()}/${data.notification.id}`; + urls.jobs = `${pages.jobs.url()}`; + urls.jobsSchedules = `${pages.jobs.url()}/schedules`; client.useCss(); client.login(); @@ -655,6 +659,26 @@ module.exports = { client.navigateTo(urls.jobTemplateSchedule); client.expect.element('#xss').not.present; client.expect.element('[class=xss]').not.present; + }, + 'check job schedules view for unsanitized content': client => { + const itemRow = `#schedules_table tr[id="${data.jobTemplateSchedule.id}"]`; + const itemName = `${itemRow} td[class*="name-"] a`; + + client.navigateTo(urls.jobsSchedules); + + client.moveToElement(itemName, 0, 0, () => { + client.expect.element(itemName).attribute('aria-describedby'); + client.getAttribute(itemName, 'aria-describedby', ({ value }) => { + const tooltip = `#${value}`; + client.expect.element(tooltip).present; + client.expect.element(tooltip).visible; + + client.expect.element('#xss').not.present; + client.expect.element('[class=xss]').not.present; + client.expect.element(tooltip).attribute('innerHTML') + .contains('<div id="xss" class="xss">test</div>'); + }); + }); client.end(); }, };