Merge pull request #3280 from hashicorp/b-ui-links-in-tables
Links in table rows should get click priority over table rows
This commit is contained in:
commit
c9220969f9
|
@ -1,4 +1,5 @@
|
|||
import Ember from 'ember';
|
||||
import { lazyClick } from '../helpers/lazy-click';
|
||||
|
||||
const { Component } = Ember;
|
||||
|
||||
|
@ -15,6 +16,6 @@ export default Component.extend({
|
|||
onClick() {},
|
||||
|
||||
click(event) {
|
||||
this.get('onClick')(event);
|
||||
lazyClick([this.get('onClick'), event]);
|
||||
},
|
||||
});
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import Ember from 'ember';
|
||||
import { lazyClick } from '../helpers/lazy-click';
|
||||
|
||||
const { Component } = Ember;
|
||||
|
||||
|
@ -11,7 +12,7 @@ export default Component.extend({
|
|||
onClick() {},
|
||||
|
||||
click(event) {
|
||||
this.get('onClick')(event);
|
||||
lazyClick([this.get('onClick'), event]);
|
||||
},
|
||||
|
||||
didReceiveAttrs() {
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import Ember from 'ember';
|
||||
import { lazyClick } from '../helpers/lazy-click';
|
||||
|
||||
const { Component } = Ember;
|
||||
|
||||
|
@ -11,7 +12,7 @@ export default Component.extend({
|
|||
onClick() {},
|
||||
|
||||
click(event) {
|
||||
this.get('onClick')(event);
|
||||
lazyClick([this.get('onClick'), event]);
|
||||
},
|
||||
|
||||
didReceiveAttrs() {
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import Ember from 'ember';
|
||||
import { lazyClick } from '../helpers/lazy-click';
|
||||
|
||||
const { Component, inject, computed } = Ember;
|
||||
|
||||
|
@ -28,6 +29,7 @@ export default Component.extend({
|
|||
}),
|
||||
|
||||
click() {
|
||||
this.get('router').transitionTo('servers.server', this.get('agent'));
|
||||
const transition = () => this.get('router').transitionTo('servers.server', this.get('agent'));
|
||||
lazyClick([transition, event]);
|
||||
},
|
||||
});
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import Ember from 'ember';
|
||||
import { lazyClick } from '../helpers/lazy-click';
|
||||
|
||||
const { Component } = Ember;
|
||||
|
||||
|
@ -12,6 +13,6 @@ export default Component.extend({
|
|||
onClick() {},
|
||||
|
||||
click(event) {
|
||||
this.get('onClick')(event);
|
||||
lazyClick([this.get('onClick'), event]);
|
||||
},
|
||||
});
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
import Ember from 'ember';
|
||||
|
||||
const { Helper, $ } = Ember;
|
||||
|
||||
/**
|
||||
* Lazy Click Event
|
||||
*
|
||||
* Usage: {{lazy-click action}}
|
||||
*
|
||||
* Calls the provided action only if the target isn't an anchor
|
||||
* that should be handled instead.
|
||||
*/
|
||||
export function lazyClick([onClick, event]) {
|
||||
if (!$(event.target).is('a')) {
|
||||
onClick(event);
|
||||
}
|
||||
}
|
||||
|
||||
export default Helper.helper(lazyClick);
|
|
@ -69,7 +69,7 @@
|
|||
Attributes
|
||||
</div>
|
||||
<div class="boxed-section-body is-full-bleed">
|
||||
{{attributes-table attributes=model.attributes.attributesStructured}}
|
||||
{{attributes-table attributes=model.attributes.attributesStructured class="attributes-table"}}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
|
|
@ -59,6 +59,7 @@
|
|||
"ember-href-to": "^1.13.0",
|
||||
"ember-load-initializers": "^1.0.0",
|
||||
"ember-moment": "^7.3.1",
|
||||
"ember-native-dom-helpers": "^0.5.4",
|
||||
"ember-resolver": "^4.0.0",
|
||||
"ember-sinon": "^0.7.0",
|
||||
"ember-source": "~2.14.0",
|
||||
|
|
|
@ -1,7 +1,11 @@
|
|||
import Ember from 'ember';
|
||||
import { click, findAll, currentURL, find, visit } from 'ember-native-dom-helpers';
|
||||
import { test } from 'qunit';
|
||||
import moduleForAcceptance from 'nomad-ui/tests/helpers/module-for-acceptance';
|
||||
import moment from 'moment';
|
||||
|
||||
const { $ } = Ember;
|
||||
|
||||
let job;
|
||||
let node;
|
||||
let allocation;
|
||||
|
@ -23,32 +27,27 @@ moduleForAcceptance('Acceptance | allocation detail', {
|
|||
test('/allocation/:id should name the allocation and link to the corresponding job and node', function(
|
||||
assert
|
||||
) {
|
||||
assert.ok(find('h1').textContent.includes(allocation.name), 'Allocation name is in the heading');
|
||||
assert.ok(find('h3').textContent.includes(job.name), 'Job name is in the subheading');
|
||||
assert.ok(
|
||||
find('h1')
|
||||
.text()
|
||||
.includes(allocation.name),
|
||||
'Allocation name is in the heading'
|
||||
);
|
||||
assert.ok(
|
||||
find('h3')
|
||||
.text()
|
||||
.includes(job.name),
|
||||
'Job name is in the subheading'
|
||||
);
|
||||
assert.ok(
|
||||
find('h3')
|
||||
.text()
|
||||
.includes(node.id.split('-')[0]),
|
||||
find('h3').textContent.includes(node.id.split('-')[0]),
|
||||
'Node short id is in the subheading'
|
||||
);
|
||||
|
||||
click('h3 a:eq(0)');
|
||||
andThen(() => {
|
||||
click(findAll('h3 a')[0]);
|
||||
});
|
||||
|
||||
andThen(() => {
|
||||
assert.equal(currentURL(), `/jobs/${job.id}`, 'Job link navigates to the job');
|
||||
});
|
||||
|
||||
visit(`/allocations/${allocation.id}`);
|
||||
click('h3 a:eq(1)');
|
||||
|
||||
andThen(() => {
|
||||
click(findAll('h3 a')[1]);
|
||||
});
|
||||
|
||||
andThen(() => {
|
||||
assert.equal(currentURL(), `/nodes/${node.id}`, 'Node link navigates to the node');
|
||||
});
|
||||
|
@ -56,7 +55,7 @@ test('/allocation/:id should name the allocation and link to the corresponding j
|
|||
|
||||
test('/allocation/:id should list all tasks for the allocation', function(assert) {
|
||||
assert.equal(
|
||||
find('.tasks tbody tr').length,
|
||||
findAll('.tasks tbody tr').length,
|
||||
server.db.taskStates.where({ allocationId: allocation.id }).length,
|
||||
'Table lists all tasks'
|
||||
);
|
||||
|
@ -68,7 +67,7 @@ test('each task row should list high-level information for the task', function(a
|
|||
.map(id => server.db.taskResources.find(id))
|
||||
.sortBy('name')[0];
|
||||
const reservedPorts = taskResources.resources.Networks[0].ReservedPorts;
|
||||
const taskRow = find('.tasks tbody tr:eq(0)');
|
||||
const taskRow = $(findAll('.tasks tbody tr')[0]);
|
||||
const events = server.db.taskEvents.where({ taskStateId: task.id });
|
||||
const event = events[events.length - 1];
|
||||
|
||||
|
@ -117,7 +116,7 @@ test('each task row should list high-level information for the task', function(a
|
|||
test('/allocation/:id should list recent events for each task', function(assert) {
|
||||
const tasks = server.db.taskStates.where({ allocationId: allocation.id });
|
||||
assert.equal(
|
||||
find('.task-state-events').length,
|
||||
findAll('.task-state-events').length,
|
||||
tasks.length,
|
||||
'A task state event block per task'
|
||||
);
|
||||
|
@ -127,7 +126,7 @@ test('each recent events list should include the name, state, and time info for
|
|||
assert
|
||||
) {
|
||||
const task = server.db.taskStates.where({ allocationId: allocation.id })[0];
|
||||
const recentEventsSection = find('.task-state-events:eq(0)');
|
||||
const recentEventsSection = $(findAll('.task-state-events')[0]);
|
||||
const heading = recentEventsSection
|
||||
.find('.message-header')
|
||||
.text()
|
||||
|
@ -146,7 +145,7 @@ test('each recent events list should list all recent events for the task', funct
|
|||
const events = server.db.taskEvents.where({ taskStateId: task.id });
|
||||
|
||||
assert.equal(
|
||||
find('.task-state-events:eq(0) .task-events tbody tr').length,
|
||||
findAll('.task-state-events')[0].querySelectorAll('.task-events tbody tr').length,
|
||||
events.length,
|
||||
`Lists ${events.length} events`
|
||||
);
|
||||
|
@ -157,7 +156,7 @@ test('each recent event should list the time, type, and description of the event
|
|||
) {
|
||||
const task = server.db.taskStates.where({ allocationId: allocation.id })[0];
|
||||
const event = server.db.taskEvents.where({ taskStateId: task.id })[0];
|
||||
const recentEvent = find('.task-state-events:eq(0) .task-events tbody tr:last');
|
||||
const recentEvent = $('.task-state-events:eq(0) .task-events tbody tr:last');
|
||||
|
||||
assert.equal(
|
||||
recentEvent
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
import Ember from 'ember';
|
||||
import { click, find, findAll, currentURL, visit } from 'ember-native-dom-helpers';
|
||||
import { test } from 'qunit';
|
||||
import moduleForAcceptance from 'nomad-ui/tests/helpers/module-for-acceptance';
|
||||
|
||||
const { $ } = Ember;
|
||||
|
||||
let node;
|
||||
|
||||
moduleForAcceptance('Acceptance | client detail', {
|
||||
|
@ -18,52 +22,45 @@ moduleForAcceptance('Acceptance | client detail', {
|
|||
});
|
||||
|
||||
test('/nodes/:id should have a breadrcumb trail linking back to nodes', function(assert) {
|
||||
assert.equal(find('.breadcrumb:eq(0)').text(), 'Nodes', 'First breadcrumb says nodes');
|
||||
assert.equal(findAll('.breadcrumb')[0].textContent, 'Nodes', 'First breadcrumb says nodes');
|
||||
assert.equal(
|
||||
find('.breadcrumb:eq(1)').text(),
|
||||
findAll('.breadcrumb')[1].textContent,
|
||||
node.id.split('-')[0],
|
||||
'Second breadcrumb says the node short id'
|
||||
);
|
||||
|
||||
click('.breadcrumb:eq(0)');
|
||||
click(findAll('.breadcrumb')[0]);
|
||||
andThen(() => {
|
||||
assert.equal(currentURL(), '/nodes', 'First breadcrumb links back to nodes');
|
||||
});
|
||||
});
|
||||
|
||||
test('/nodes/:id should list immediate details for the node in the title', function(assert) {
|
||||
assert.ok(find('.title').textContent.includes(node.name), 'Title includes name');
|
||||
assert.ok(find('.title').textContent.includes(node.id), 'Title includes id');
|
||||
assert.ok(
|
||||
find('.title')
|
||||
.text()
|
||||
.includes(node.name),
|
||||
'Title includes name'
|
||||
findAll(`.title .node-status-light.${node.status}`).length,
|
||||
'Title includes status light'
|
||||
);
|
||||
assert.ok(
|
||||
find('.title')
|
||||
.text()
|
||||
.includes(node.id),
|
||||
'Title includes id'
|
||||
);
|
||||
assert.ok(find(`.title .node-status-light.${node.status}`).length, 'Title includes status light');
|
||||
});
|
||||
|
||||
test('/nodes/:id should list additional detail for the node below the title', function(assert) {
|
||||
assert.equal(
|
||||
find('.inline-definitions .pair:eq(0)').text(),
|
||||
findAll('.inline-definitions .pair')[0].textContent,
|
||||
`Status ${node.status}`,
|
||||
'Status is in additional details'
|
||||
);
|
||||
assert.ok(
|
||||
find('.inline-definitions .pair:eq(0) .status-text').hasClass(`node-${node.status}`),
|
||||
$('.inline-definitions .pair:eq(0) .status-text').hasClass(`node-${node.status}`),
|
||||
'Status is decorated with a status class'
|
||||
);
|
||||
assert.equal(
|
||||
find('.inline-definitions .pair:eq(1)').text(),
|
||||
findAll('.inline-definitions .pair')[1].textContent,
|
||||
`Address ${node.httpAddr}`,
|
||||
'Address is in additional detals'
|
||||
);
|
||||
assert.equal(
|
||||
find('.inline-definitions .pair:eq(2)').text(),
|
||||
findAll('.inline-definitions .pair')[2].textContent,
|
||||
`Datacenter ${node.datacenter}`,
|
||||
'Datacenter is in additional details'
|
||||
);
|
||||
|
@ -72,14 +69,14 @@ test('/nodes/:id should list additional detail for the node below the title', fu
|
|||
test('/nodes/:id should list all allocations on the node', function(assert) {
|
||||
const allocationsCount = server.db.allocations.where({ nodeId: node.id }).length;
|
||||
assert.equal(
|
||||
find('.allocations tbody tr').length,
|
||||
findAll('.allocations tbody tr').length,
|
||||
allocationsCount,
|
||||
`Allocations table lists all ${allocationsCount} associated allocations`
|
||||
);
|
||||
});
|
||||
|
||||
test('each allocation should have high-level details for the allocation', function(assert) {
|
||||
const allocationRow = find('.allocations tbody tr:eq(0)');
|
||||
const allocationRow = $(findAll('.allocations tbody tr')[0]);
|
||||
const allocation = server.db.allocations
|
||||
.where({ nodeId: node.id })
|
||||
.sortBy('modifyIndex')
|
||||
|
@ -156,7 +153,7 @@ test('each allocation should link to the allocation detail page', function(asser
|
|||
.sortBy('modifyIndex')
|
||||
.reverse()[0];
|
||||
|
||||
click('.allocations tbody tr:eq(0) td:eq(0) a');
|
||||
click($('.allocations tbody tr:eq(0) td:eq(0) a').get(0));
|
||||
|
||||
andThen(() => {
|
||||
assert.equal(
|
||||
|
@ -170,7 +167,7 @@ test('each allocation should link to the allocation detail page', function(asser
|
|||
test('each allocation should link to the job the allocation belongs to', function(assert) {
|
||||
const allocation = server.db.allocations.where({ nodeId: node.id })[0];
|
||||
const job = server.db.jobs.find(allocation.jobId);
|
||||
click('.allocations tbody tr:eq(0) td:eq(3) a');
|
||||
click($('.allocations tbody tr:eq(0) td:eq(3) a').get(0));
|
||||
|
||||
andThen(() => {
|
||||
assert.equal(
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
import { findAll, currentURL, visit } from 'ember-native-dom-helpers';
|
||||
import { test } from 'qunit';
|
||||
import moduleForAcceptance from 'nomad-ui/tests/helpers/module-for-acceptance';
|
||||
|
||||
let job;
|
||||
|
||||
moduleForAcceptance('Acceptance | job detail', {
|
||||
moduleForAcceptance('Acceptance | job definition', {
|
||||
beforeEach() {
|
||||
server.create('node');
|
||||
server.create('job');
|
||||
|
@ -17,7 +18,7 @@ test('visiting /jobs/:job_id/definition', function(assert) {
|
|||
});
|
||||
|
||||
test('the job definition page contains a json viewer component', function(assert) {
|
||||
assert.ok(find('.json-viewer').length, 'JSON viewer found');
|
||||
assert.ok(findAll('.json-viewer').length, 'JSON viewer found');
|
||||
});
|
||||
|
||||
test('the job definition page requests the job to display in an unmutated form', function(assert) {
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
import { click, findAll, find, visit } from 'ember-native-dom-helpers';
|
||||
import Ember from 'ember';
|
||||
import { test } from 'qunit';
|
||||
import moment from 'moment';
|
||||
import moduleForAcceptance from 'nomad-ui/tests/helpers/module-for-acceptance';
|
||||
|
||||
const { get } = Ember;
|
||||
const { get, $ } = Ember;
|
||||
const sum = (list, key) => list.reduce((sum, item) => sum + get(item, key), 0);
|
||||
|
||||
let job;
|
||||
|
@ -32,7 +33,7 @@ test('/jobs/:id/deployments should list all job deployments', function(assert) {
|
|||
visit(`/jobs/${job.id}/deployments`);
|
||||
andThen(() => {
|
||||
assert.ok(
|
||||
find('.timeline-object').length,
|
||||
findAll('.timeline-object').length,
|
||||
deployments.length,
|
||||
'Each deployment gets a row in the timeline'
|
||||
);
|
||||
|
@ -50,7 +51,7 @@ test('each deployment mentions the deployment shortId, status, version, and time
|
|||
jobId: deployment.jobId,
|
||||
version: deployment.versionNumber,
|
||||
});
|
||||
const deploymentRow = find('.timeline-object:eq(0)');
|
||||
const deploymentRow = $(findAll('.timeline-object')[0]);
|
||||
|
||||
assert.ok(deploymentRow.text().includes(deployment.id.split('-')[0]), 'Short ID');
|
||||
assert.equal(deploymentRow.find('.tag').text(), deployment.status, 'Status');
|
||||
|
@ -89,7 +90,7 @@ test('when the deployment is running and needs promotion, the deployment item sa
|
|||
visit(`/jobs/${job.id}/deployments`);
|
||||
|
||||
andThen(() => {
|
||||
const deploymentRow = find('.timeline-object:eq(0)');
|
||||
const deploymentRow = $(findAll('.timeline-object')[0]);
|
||||
assert.ok(
|
||||
deploymentRow.find('.badge:contains("Requires Promotion")').length,
|
||||
'Requires Promotion badge found'
|
||||
|
@ -103,11 +104,11 @@ test('each deployment item can be opened to show details', function(assert) {
|
|||
visit(`/jobs/${job.id}/deployments`);
|
||||
|
||||
andThen(() => {
|
||||
deploymentRow = find('.timeline-object:eq(0)');
|
||||
deploymentRow = $(findAll('.timeline-object')[0]);
|
||||
|
||||
assert.ok(deploymentRow.find('.boxed-section-body').length === 0, 'No deployment body');
|
||||
|
||||
click(deploymentRow.find('button'));
|
||||
click(deploymentRow.find('button').get(0));
|
||||
|
||||
andThen(() => {
|
||||
assert.ok(deploymentRow.find('.boxed-section-body').length, 'Deployment body found');
|
||||
|
@ -120,18 +121,18 @@ test('when open, a deployment shows the deployment metrics', function(assert) {
|
|||
|
||||
andThen(() => {
|
||||
const deployment = sortedDeployments.models[0];
|
||||
const deploymentRow = find('.timeline-object:eq(0)');
|
||||
const deploymentRow = $(findAll('.timeline-object')[0]);
|
||||
const taskGroupSummaries = deployment.deploymentTaskGroupSummaryIds.map(id =>
|
||||
server.db.deploymentTaskGroupSummaries.find(id)
|
||||
);
|
||||
|
||||
click(deploymentRow.find('button'));
|
||||
click(deploymentRow.find('button').get(0));
|
||||
|
||||
andThen(() => {
|
||||
assert.equal(
|
||||
find('.deployment-metrics .label:contains("Canaries") + .value')
|
||||
.text()
|
||||
.trim(),
|
||||
$('.deployment-metrics .label:contains("Canaries") + .value')
|
||||
.get(0)
|
||||
.textContent.trim(),
|
||||
`${sum(taskGroupSummaries, 'placedCanaries')} / ${sum(
|
||||
taskGroupSummaries,
|
||||
'desiredCanaries'
|
||||
|
@ -140,41 +141,39 @@ test('when open, a deployment shows the deployment metrics', function(assert) {
|
|||
);
|
||||
|
||||
assert.equal(
|
||||
find('.deployment-metrics .label:contains("Placed") + .value')
|
||||
.text()
|
||||
.trim(),
|
||||
$('.deployment-metrics .label:contains("Placed") + .value')
|
||||
.get(0)
|
||||
.textContent.trim(),
|
||||
sum(taskGroupSummaries, 'placedAllocs'),
|
||||
'Placed allocs aggregates across task groups'
|
||||
);
|
||||
|
||||
assert.equal(
|
||||
find('.deployment-metrics .label:contains("Desired") + .value')
|
||||
.text()
|
||||
.trim(),
|
||||
$('.deployment-metrics .label:contains("Desired") + .value')
|
||||
.get(0)
|
||||
.textContent.trim(),
|
||||
sum(taskGroupSummaries, 'desiredTotal'),
|
||||
'Desired allocs aggregates across task groups'
|
||||
);
|
||||
|
||||
assert.equal(
|
||||
find('.deployment-metrics .label:contains("Healthy") + .value')
|
||||
.text()
|
||||
.trim(),
|
||||
$('.deployment-metrics .label:contains("Healthy") + .value')
|
||||
.get(0)
|
||||
.textContent.trim(),
|
||||
sum(taskGroupSummaries, 'healthyAllocs'),
|
||||
'Healthy allocs aggregates across task groups'
|
||||
);
|
||||
|
||||
assert.equal(
|
||||
find('.deployment-metrics .label:contains("Unhealthy") + .value')
|
||||
.text()
|
||||
.trim(),
|
||||
$('.deployment-metrics .label:contains("Unhealthy") + .value')
|
||||
.get(0)
|
||||
.textContent.trim(),
|
||||
sum(taskGroupSummaries, 'unhealthyAllocs'),
|
||||
'Unhealthy allocs aggregates across task groups'
|
||||
);
|
||||
|
||||
assert.equal(
|
||||
find('.deployment-metrics .notification')
|
||||
.text()
|
||||
.trim(),
|
||||
find('.deployment-metrics .notification').textContent.trim(),
|
||||
deployment.statusDescription,
|
||||
'Status description is in the metrics block'
|
||||
);
|
||||
|
@ -189,12 +188,12 @@ test('when open, a deployment shows a list of all task groups and their respecti
|
|||
|
||||
andThen(() => {
|
||||
const deployment = sortedDeployments.models[0];
|
||||
const deploymentRow = find('.timeline-object:eq(0)');
|
||||
const deploymentRow = $(findAll('.timeline-object')[0]);
|
||||
const taskGroupSummaries = deployment.deploymentTaskGroupSummaryIds.map(id =>
|
||||
server.db.deploymentTaskGroupSummaries.find(id)
|
||||
);
|
||||
|
||||
click(deploymentRow.find('button'));
|
||||
click(deploymentRow.find('button').get(0));
|
||||
|
||||
andThen(() => {
|
||||
assert.ok(
|
||||
|
@ -282,13 +281,13 @@ test('when open, a deployment shows a list of all allocations for the deployment
|
|||
|
||||
andThen(() => {
|
||||
const deployment = sortedDeployments.models[0];
|
||||
const deploymentRow = find('.timeline-object:eq(0)');
|
||||
const deploymentRow = $(findAll('.timeline-object')[0]);
|
||||
|
||||
// TODO: Make this less brittle. This logic is copied from the mirage config,
|
||||
// since there is no reference to allocations on the deployment model.
|
||||
const allocations = server.db.allocations.where({ jobId: deployment.jobId }).slice(0, 3);
|
||||
|
||||
click(deploymentRow.find('button'));
|
||||
click(deploymentRow.find('button').get(0));
|
||||
|
||||
andThen(() => {
|
||||
assert.ok(
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
import { click, findAll, currentURL, find, visit } from 'ember-native-dom-helpers';
|
||||
import Ember from 'ember';
|
||||
import moment from 'moment';
|
||||
import { test } from 'qunit';
|
||||
import moduleForAcceptance from 'nomad-ui/tests/helpers/module-for-acceptance';
|
||||
|
||||
const { get } = Ember;
|
||||
const { get, $ } = Ember;
|
||||
const sum = (list, key) => list.reduce((sum, item) => sum + get(item, key), 0);
|
||||
|
||||
let job;
|
||||
|
@ -22,39 +23,28 @@ test('visiting /jobs/:job_id', function(assert) {
|
|||
});
|
||||
|
||||
test('breadcrumbs includes job name and link back to the jobs list', function(assert) {
|
||||
assert.equal(find('.breadcrumb:eq(0)').text(), 'Jobs', 'First breadcrumb says jobs');
|
||||
assert.equal(find('.breadcrumb:eq(1)').text(), job.name, 'Second breadcrumb says the job name');
|
||||
assert.equal(findAll('.breadcrumb')[0].textContent, 'Jobs', 'First breadcrumb says jobs');
|
||||
assert.equal(
|
||||
findAll('.breadcrumb')[1].textContent,
|
||||
job.name,
|
||||
'Second breadcrumb says the job name'
|
||||
);
|
||||
|
||||
click('.breadcrumb:eq(0)');
|
||||
click(findAll('.breadcrumb')[0]);
|
||||
andThen(() => {
|
||||
assert.equal(currentURL(), '/jobs', 'First breadcrumb links back to jobs');
|
||||
});
|
||||
});
|
||||
|
||||
test('the job detail page should contain basic information about the job', function(assert) {
|
||||
assert.ok(
|
||||
find('.title .tag:eq(0)')
|
||||
.text()
|
||||
.includes(job.status),
|
||||
'Status'
|
||||
);
|
||||
assert.ok(
|
||||
find('.job-stats span:eq(0)')
|
||||
.text()
|
||||
.includes(job.type),
|
||||
'Type'
|
||||
);
|
||||
assert.ok(
|
||||
find('.job-stats span:eq(1)')
|
||||
.text()
|
||||
.includes(job.priority),
|
||||
'Priority'
|
||||
);
|
||||
assert.ok(findAll('.title .tag')[0].textContent.includes(job.status), 'Status');
|
||||
assert.ok(findAll('.job-stats span')[0].textContent.includes(job.type), 'Type');
|
||||
assert.ok(findAll('.job-stats span')[1].textContent.includes(job.priority), 'Priority');
|
||||
});
|
||||
|
||||
test('the job detail page should list all task groups', function(assert) {
|
||||
assert.equal(
|
||||
find('.task-group-row').length,
|
||||
findAll('.task-group-row').length,
|
||||
server.db.taskGroups.where({ jobId: job.id }).length
|
||||
);
|
||||
});
|
||||
|
@ -63,7 +53,7 @@ test('each row in the task group table should show basic information about the t
|
|||
assert
|
||||
) {
|
||||
const taskGroup = job.taskGroupIds.map(id => server.db.taskGroups.find(id)).sortBy('name')[0];
|
||||
const taskGroupRow = find('.task-group-row:eq(0)');
|
||||
const taskGroupRow = $(findAll('.task-group-row')[0]);
|
||||
const tasks = server.db.tasks.where({ taskGroupId: taskGroup.id });
|
||||
const sum = (list, key) => list.reduce((sum, item) => sum + get(item, key), 0);
|
||||
|
||||
|
@ -104,37 +94,37 @@ test('the allocations diagram lists all allocation status figures', function(ass
|
|||
);
|
||||
|
||||
assert.equal(
|
||||
legend.find('li.queued .value').text(),
|
||||
legend.querySelector('li.queued .value').textContent,
|
||||
statusCounts.queued,
|
||||
`${statusCounts.queued} are queued`
|
||||
);
|
||||
|
||||
assert.equal(
|
||||
legend.find('li.starting .value').text(),
|
||||
legend.querySelector('li.starting .value').textContent,
|
||||
statusCounts.starting,
|
||||
`${statusCounts.starting} are starting`
|
||||
);
|
||||
|
||||
assert.equal(
|
||||
legend.find('li.running .value').text(),
|
||||
legend.querySelector('li.running .value').textContent,
|
||||
statusCounts.running,
|
||||
`${statusCounts.running} are running`
|
||||
);
|
||||
|
||||
assert.equal(
|
||||
legend.find('li.complete .value').text(),
|
||||
legend.querySelector('li.complete .value').textContent,
|
||||
statusCounts.complete,
|
||||
`${statusCounts.complete} are complete`
|
||||
);
|
||||
|
||||
assert.equal(
|
||||
legend.find('li.failed .value').text(),
|
||||
legend.querySelector('li.failed .value').textContent,
|
||||
statusCounts.failed,
|
||||
`${statusCounts.failed} are failed`
|
||||
);
|
||||
|
||||
assert.equal(
|
||||
legend.find('li.lost .value').text(),
|
||||
legend.querySelector('li.lost .value').textContent,
|
||||
statusCounts.lost,
|
||||
`${statusCounts.lost} are lost`
|
||||
);
|
||||
|
@ -149,7 +139,7 @@ test('there is no active deployment section when the job has no active deploymen
|
|||
visit(`/jobs/${job.id}`);
|
||||
|
||||
andThen(() => {
|
||||
assert.ok(find('.active-deployment').length === 0, 'No active deployment');
|
||||
assert.ok(findAll('.active-deployment').length === 0, 'No active deployment');
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -168,27 +158,27 @@ test('the active deployment section shows up for the currently running deploymen
|
|||
visit(`/jobs/${job.id}`);
|
||||
|
||||
andThen(() => {
|
||||
assert.ok(find('.active-deployment').length === 1, 'Active deployment');
|
||||
assert.ok(findAll('.active-deployment').length === 1, 'Active deployment');
|
||||
assert.equal(
|
||||
find('.active-deployment > .boxed-section-head .badge')
|
||||
.text()
|
||||
.trim(),
|
||||
$('.active-deployment > .boxed-section-head .badge')
|
||||
.get(0)
|
||||
.textContent.trim(),
|
||||
deployment.id.split('-')[0],
|
||||
'The active deployment is the most recent running deployment'
|
||||
);
|
||||
|
||||
assert.equal(
|
||||
find('.active-deployment > .boxed-section-head .submit-time')
|
||||
.text()
|
||||
.trim(),
|
||||
$('.active-deployment > .boxed-section-head .submit-time')
|
||||
.get(0)
|
||||
.textContent.trim(),
|
||||
moment(version.submitTime / 1000000).fromNow(),
|
||||
'Time since the job was submitted is in the active deployment header'
|
||||
);
|
||||
|
||||
assert.equal(
|
||||
find('.deployment-metrics .label:contains("Canaries") + .value')
|
||||
.text()
|
||||
.trim(),
|
||||
$('.deployment-metrics .label:contains("Canaries") + .value')
|
||||
.get(0)
|
||||
.textContent.trim(),
|
||||
`${sum(taskGroupSummaries, 'placedCanaries')} / ${sum(
|
||||
taskGroupSummaries,
|
||||
'desiredCanaries'
|
||||
|
@ -197,41 +187,41 @@ test('the active deployment section shows up for the currently running deploymen
|
|||
);
|
||||
|
||||
assert.equal(
|
||||
find('.deployment-metrics .label:contains("Placed") + .value')
|
||||
.text()
|
||||
.trim(),
|
||||
$('.deployment-metrics .label:contains("Placed") + .value')
|
||||
.get(0)
|
||||
.textContent.trim(),
|
||||
sum(taskGroupSummaries, 'placedAllocs'),
|
||||
'Placed allocs aggregates across task groups'
|
||||
);
|
||||
|
||||
assert.equal(
|
||||
find('.deployment-metrics .label:contains("Desired") + .value')
|
||||
.text()
|
||||
.trim(),
|
||||
$('.deployment-metrics .label:contains("Desired") + .value')
|
||||
.get(0)
|
||||
.textContent.trim(),
|
||||
sum(taskGroupSummaries, 'desiredTotal'),
|
||||
'Desired allocs aggregates across task groups'
|
||||
);
|
||||
|
||||
assert.equal(
|
||||
find('.deployment-metrics .label:contains("Healthy") + .value')
|
||||
.text()
|
||||
.trim(),
|
||||
$('.deployment-metrics .label:contains("Healthy") + .value')
|
||||
.get(0)
|
||||
.textContent.trim(),
|
||||
sum(taskGroupSummaries, 'healthyAllocs'),
|
||||
'Healthy allocs aggregates across task groups'
|
||||
);
|
||||
|
||||
assert.equal(
|
||||
find('.deployment-metrics .label:contains("Unhealthy") + .value')
|
||||
.text()
|
||||
.trim(),
|
||||
$('.deployment-metrics .label:contains("Unhealthy") + .value')
|
||||
.get(0)
|
||||
.textContent.trim(),
|
||||
sum(taskGroupSummaries, 'unhealthyAllocs'),
|
||||
'Unhealthy allocs aggregates across task groups'
|
||||
);
|
||||
|
||||
assert.equal(
|
||||
find('.deployment-metrics .notification')
|
||||
.text()
|
||||
.trim(),
|
||||
$('.deployment-metrics .notification')
|
||||
.get(0)
|
||||
.textContent.trim(),
|
||||
deployment.statusDescription,
|
||||
'Status description is in the metrics block'
|
||||
);
|
||||
|
@ -246,24 +236,26 @@ test('the active deployment section can be expanded to show task groups and allo
|
|||
|
||||
andThen(() => {
|
||||
assert.ok(
|
||||
find('.active-deployment .boxed-section-head:contains("Task Groups")').length === 0,
|
||||
$('.active-deployment .boxed-section-head:contains("Task Groups")').length === 0,
|
||||
'Task groups not found'
|
||||
);
|
||||
assert.ok(
|
||||
find('.active-deployment .boxed-section-head:contains("Allocations")').length === 0,
|
||||
$('.active-deployment .boxed-section-head:contains("Allocations")').length === 0,
|
||||
'Allocations not found'
|
||||
);
|
||||
});
|
||||
|
||||
click('.active-deployment-details-toggle');
|
||||
andThen(() => {
|
||||
click('.active-deployment-details-toggle');
|
||||
});
|
||||
|
||||
andThen(() => {
|
||||
assert.ok(
|
||||
find('.active-deployment .boxed-section-head:contains("Task Groups")').length === 1,
|
||||
$('.active-deployment .boxed-section-head:contains("Task Groups")').length === 1,
|
||||
'Task groups found'
|
||||
);
|
||||
assert.ok(
|
||||
find('.active-deployment .boxed-section-head:contains("Allocations")').length === 1,
|
||||
$('.active-deployment .boxed-section-head:contains("Allocations")').length === 1,
|
||||
'Allocations found'
|
||||
);
|
||||
});
|
||||
|
|
|
@ -1,7 +1,11 @@
|
|||
import Ember from 'ember';
|
||||
import { findAll, visit } from 'ember-native-dom-helpers';
|
||||
import { test } from 'qunit';
|
||||
import moduleForAcceptance from 'nomad-ui/tests/helpers/module-for-acceptance';
|
||||
import moment from 'moment';
|
||||
|
||||
const { $ } = Ember;
|
||||
|
||||
let job;
|
||||
let versions;
|
||||
|
||||
|
@ -16,7 +20,7 @@ moduleForAcceptance('Acceptance | job versions', {
|
|||
|
||||
test('/jobs/:id/versions should list all job versions', function(assert) {
|
||||
assert.ok(
|
||||
find('.timeline-object').length,
|
||||
findAll('.timeline-object').length,
|
||||
versions.length,
|
||||
'Each version gets a row in the timeline'
|
||||
);
|
||||
|
@ -26,7 +30,7 @@ test('each version mentions the version number, the stability, and the submitted
|
|||
assert
|
||||
) {
|
||||
const version = versions.sortBy('submitTime').reverse()[0];
|
||||
const versionRow = find('.timeline-object:eq(0)');
|
||||
const versionRow = $(findAll('.timeline-object')[0]);
|
||||
|
||||
assert.ok(versionRow.text().includes(`Version #${version.version}`), 'Version #');
|
||||
assert.equal(
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
import Ember from 'ember';
|
||||
import { click, findAll, currentURL, visit } from 'ember-native-dom-helpers';
|
||||
import { test } from 'qunit';
|
||||
import moduleForAcceptance from 'nomad-ui/tests/helpers/module-for-acceptance';
|
||||
|
||||
const { $ } = Ember;
|
||||
|
||||
moduleForAcceptance('Acceptance | jobs list', {
|
||||
beforeEach() {
|
||||
// Required for placing allocations (a result of creating jobs)
|
||||
|
@ -25,10 +29,10 @@ test('/jobs should list the first page of jobs sorted by modify index', function
|
|||
|
||||
andThen(() => {
|
||||
const sortedJobs = server.db.jobs.sortBy('modifyIndex').reverse();
|
||||
assert.equal(find('.job-row').length, pageSize);
|
||||
assert.equal(findAll('.job-row').length, pageSize);
|
||||
for (var jobNumber = 0; jobNumber < pageSize; jobNumber++) {
|
||||
assert.equal(
|
||||
find(`.job-row:eq(${jobNumber}) td:eq(0)`).text(),
|
||||
$(`.job-row:eq(${jobNumber}) td:eq(0)`).text(),
|
||||
sortedJobs[jobNumber].name,
|
||||
'Jobs are ordered'
|
||||
);
|
||||
|
@ -44,11 +48,18 @@ test('each job row should contain information about the job', function(assert) {
|
|||
visit('/jobs');
|
||||
|
||||
andThen(() => {
|
||||
const jobRow = find('.job-row:eq(0)');
|
||||
const jobRow = $(findAll('.job-row')[0]);
|
||||
|
||||
assert.equal(jobRow.find('td:eq(0)').text(), job.name, 'Name');
|
||||
assert.equal(jobRow.find('td:eq(0) a').attr('href'), `/ui/jobs/${job.id}`, 'Detail Link');
|
||||
assert.equal(jobRow.find('td:eq(1)').text().trim(), job.status, 'Status');
|
||||
assert.equal(
|
||||
jobRow
|
||||
.find('td:eq(1)')
|
||||
.text()
|
||||
.trim(),
|
||||
job.status,
|
||||
'Status'
|
||||
);
|
||||
assert.equal(jobRow.find('td:eq(2)').text(), job.type, 'Type');
|
||||
assert.equal(jobRow.find('td:eq(3)').text(), job.priority, 'Priority');
|
||||
assert.equal(jobRow.find('td:eq(4)').text(), taskGroups.length, '# Groups');
|
||||
|
@ -60,7 +71,10 @@ test('each job row should link to the corresponding job', function(assert) {
|
|||
const job = server.db.jobs[0];
|
||||
|
||||
visit('/jobs');
|
||||
click('.job-row:eq(0) td:eq(0) a');
|
||||
|
||||
andThen(() => {
|
||||
click($('.job-row:eq(0) td:eq(0) a').get(0));
|
||||
});
|
||||
|
||||
andThen(() => {
|
||||
assert.equal(currentURL(), `/jobs/${job.id}`);
|
||||
|
|
|
@ -1,8 +1,12 @@
|
|||
import Ember from 'ember';
|
||||
import { click, findAll, currentURL, visit } from 'ember-native-dom-helpers';
|
||||
import { test } from 'qunit';
|
||||
import moduleForAcceptance from 'nomad-ui/tests/helpers/module-for-acceptance';
|
||||
import { findLeader } from '../../mirage/config';
|
||||
import ipParts from 'nomad-ui/utils/ip-parts';
|
||||
|
||||
const { $ } = Ember;
|
||||
|
||||
function minimumSetup() {
|
||||
server.createList('node', 1);
|
||||
server.createList('agent', 1);
|
||||
|
@ -21,14 +25,14 @@ test('/nodes should list one page of clients', function(assert) {
|
|||
visit('/nodes');
|
||||
|
||||
andThen(() => {
|
||||
assert.equal(find('.client-node-row').length, pageSize);
|
||||
assert.ok(find('.pagination').length, 'Pagination found on the page');
|
||||
assert.equal(findAll('.client-node-row').length, pageSize);
|
||||
assert.ok(findAll('.pagination').length, 'Pagination found on the page');
|
||||
|
||||
const sortedNodes = server.db.nodes.sortBy('modifyIndex').reverse();
|
||||
|
||||
for (var nodeNumber = 0; nodeNumber < pageSize; nodeNumber++) {
|
||||
assert.equal(
|
||||
find(`.client-node-row:eq(${nodeNumber}) td:eq(0)`).text(),
|
||||
$(`.client-node-row:eq(${nodeNumber}) td:eq(0)`).text(),
|
||||
sortedNodes[nodeNumber].id.split('-')[0],
|
||||
'Nodes are ordered'
|
||||
);
|
||||
|
@ -43,7 +47,7 @@ test('each client record should show high-level info of the client', function(as
|
|||
visit('/nodes');
|
||||
|
||||
andThen(() => {
|
||||
const nodeRow = find('.client-node-row:eq(0)');
|
||||
const nodeRow = $(findAll('.client-node-row')[0]);
|
||||
const allocations = server.db.allocations.where({ nodeId: node.id });
|
||||
const { address, port } = ipParts(node.httpAddr);
|
||||
|
||||
|
@ -62,7 +66,9 @@ test('each client should link to the client detail page', function(assert) {
|
|||
const node = server.db.nodes[0];
|
||||
|
||||
visit('/nodes');
|
||||
click('.client-node-row:eq(0)');
|
||||
andThen(() => {
|
||||
click(findAll('.client-node-row')[0]);
|
||||
});
|
||||
|
||||
andThen(() => {
|
||||
assert.equal(currentURL(), `/nodes/${node.id}`);
|
||||
|
@ -81,7 +87,7 @@ test('/servers should list all servers', function(assert) {
|
|||
visit('/servers');
|
||||
|
||||
andThen(() => {
|
||||
assert.equal(find('.server-agent-row').length, pageSize);
|
||||
assert.equal(findAll('.server-agent-row').length, pageSize);
|
||||
|
||||
const sortedAgents = server.db.agents
|
||||
.sort((a, b) => {
|
||||
|
@ -96,7 +102,7 @@ test('/servers should list all servers', function(assert) {
|
|||
|
||||
for (var agentNumber = 0; agentNumber < 8; agentNumber++) {
|
||||
assert.equal(
|
||||
find(`.server-agent-row:eq(${agentNumber}) td:eq(0)`).text(),
|
||||
$(`.server-agent-row:eq(${agentNumber}) td:eq(0)`).text(),
|
||||
sortedAgents[agentNumber].name,
|
||||
'Clients are ordered'
|
||||
);
|
||||
|
@ -111,7 +117,7 @@ test('each server should show high-level info of the server', function(assert) {
|
|||
visit('/servers');
|
||||
|
||||
andThen(() => {
|
||||
const agentRow = find('.server-agent-row:eq(0)');
|
||||
const agentRow = $(findAll('.server-agent-row')[0]);
|
||||
|
||||
assert.equal(agentRow.find('td:eq(0)').text(), agent.name, 'Name');
|
||||
assert.equal(agentRow.find('td:eq(1)').text(), agent.status, 'Status');
|
||||
|
@ -127,7 +133,9 @@ test('each server should link to the server detail page', function(assert) {
|
|||
const agent = server.db.agents[0];
|
||||
|
||||
visit('/servers');
|
||||
click('.server-agent-row:eq(0)');
|
||||
andThen(() => {
|
||||
click(findAll('.server-agent-row')[0]);
|
||||
});
|
||||
|
||||
andThen(() => {
|
||||
assert.equal(currentURL(), `/servers/${agent.name}`);
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
import Ember from 'ember';
|
||||
import { findAll, currentURL, visit } from 'ember-native-dom-helpers';
|
||||
import { test } from 'qunit';
|
||||
import moduleForAcceptance from 'nomad-ui/tests/helpers/module-for-acceptance';
|
||||
|
||||
const { $ } = Ember;
|
||||
|
||||
let agent;
|
||||
|
||||
moduleForAcceptance('Acceptance | server detail', {
|
||||
|
@ -18,22 +22,22 @@ test('visiting /servers/:server_name', function(assert) {
|
|||
test('the server detail page should list all tags for the server', function(assert) {
|
||||
const tags = agent.tags;
|
||||
|
||||
assert.equal(find('.server-tags tbody tr').length, Object.keys(tags).length, '# of tags');
|
||||
assert.equal(findAll('.server-tags tbody tr').length, Object.keys(tags).length, '# of tags');
|
||||
Object.keys(tags).forEach((key, index) => {
|
||||
const row = find(`.server-tags tbody tr:eq(${index})`);
|
||||
const row = $(`.server-tags tbody tr:eq(${index})`);
|
||||
assert.equal(row.find('td:eq(0)').text(), key, `Label: ${key}`);
|
||||
assert.equal(row.find('td:eq(1)').text(), tags[key], `Value: ${tags[key]}`);
|
||||
});
|
||||
});
|
||||
|
||||
test('the list of servers from /servers should still be present', function(assert) {
|
||||
assert.equal(find('.server-agent-row').length, server.db.agents.length, '# of servers');
|
||||
assert.equal(findAll('.server-agent-row').length, server.db.agents.length, '# of servers');
|
||||
});
|
||||
|
||||
test('the active server should be denoted in the table', function(assert) {
|
||||
assert.equal(find('.server-agent-row.is-active').length, 1, 'Only one active server');
|
||||
assert.equal(findAll('.server-agent-row.is-active').length, 1, 'Only one active server');
|
||||
assert.equal(
|
||||
find('.server-agent-row.is-active td:eq(0)').text(),
|
||||
findAll('.server-agent-row.is-active td')[0].textContent,
|
||||
agent.name,
|
||||
'Active server matches current route'
|
||||
);
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
import Ember from 'ember';
|
||||
import { click, findAll, currentURL, visit } from 'ember-native-dom-helpers';
|
||||
import { test } from 'qunit';
|
||||
import moduleForAcceptance from 'nomad-ui/tests/helpers/module-for-acceptance';
|
||||
|
||||
const { $ } = Ember;
|
||||
|
||||
let job;
|
||||
let taskGroup;
|
||||
let tasks;
|
||||
|
@ -10,6 +14,7 @@ const sum = (total, n) => total + n;
|
|||
|
||||
moduleForAcceptance('Acceptance | task group detail', {
|
||||
beforeEach() {
|
||||
server.create('agent');
|
||||
server.create('node', 'forceIPv4');
|
||||
|
||||
job = server.create('job', {
|
||||
|
@ -46,39 +51,43 @@ test('/jobs/:id/:task-group should list high-level metrics for the allocation',
|
|||
const totalDisk = taskGroup.ephemeralDisk.SizeMB;
|
||||
|
||||
assert.equal(
|
||||
find('.inline-definitions .pair:eq(0)').text(),
|
||||
findAll('.inline-definitions .pair')[0].textContent,
|
||||
`# Tasks ${tasks.length}`,
|
||||
'# Tasks'
|
||||
);
|
||||
assert.equal(
|
||||
find('.inline-definitions .pair:eq(1)').text(),
|
||||
findAll('.inline-definitions .pair')[1].textContent,
|
||||
`Reserved CPU ${totalCPU} MHz`,
|
||||
'Aggregated CPU reservation for all tasks'
|
||||
);
|
||||
assert.equal(
|
||||
find('.inline-definitions .pair:eq(2)').text(),
|
||||
findAll('.inline-definitions .pair')[2].textContent,
|
||||
`Reserved Memory ${totalMemory} MiB`,
|
||||
'Aggregated Memory reservation for all tasks'
|
||||
);
|
||||
assert.equal(
|
||||
find('.inline-definitions .pair:eq(3)').text(),
|
||||
findAll('.inline-definitions .pair')[3].textContent,
|
||||
`Reserved Disk ${totalDisk} MiB`,
|
||||
'Aggregated Disk reservation for all tasks'
|
||||
);
|
||||
});
|
||||
|
||||
test('/jobs/:id/:task-group should have breadcrumbs for job and jobs', function(assert) {
|
||||
assert.equal(find('.breadcrumb:eq(0)').text(), 'Jobs', 'First breadcrumb says jobs');
|
||||
assert.equal(find('.breadcrumb:eq(1)').text(), job.name, 'Second breadcrumb says the job name');
|
||||
assert.equal(findAll('.breadcrumb')[0].textContent, 'Jobs', 'First breadcrumb says jobs');
|
||||
assert.equal(
|
||||
find('.breadcrumb:eq(2)').text(),
|
||||
findAll('.breadcrumb')[1].textContent,
|
||||
job.name,
|
||||
'Second breadcrumb says the job name'
|
||||
);
|
||||
assert.equal(
|
||||
findAll('.breadcrumb')[2].textContent,
|
||||
taskGroup.name,
|
||||
'Third breadcrumb says the job name'
|
||||
);
|
||||
});
|
||||
|
||||
test('/jobs/:id/:task-group first breadcrumb should link to jobs', function(assert) {
|
||||
click('.breadcrumb:eq(0)');
|
||||
click(findAll('.breadcrumb')[0]);
|
||||
andThen(() => {
|
||||
assert.equal(currentURL(), '/jobs', 'First breadcrumb links back to jobs');
|
||||
});
|
||||
|
@ -87,7 +96,7 @@ test('/jobs/:id/:task-group first breadcrumb should link to jobs', function(asse
|
|||
test('/jobs/:id/:task-group second breadcrumb should link to the job for the task group', function(
|
||||
assert
|
||||
) {
|
||||
click('.breadcrumb:eq(1)');
|
||||
click(findAll('.breadcrumb')[1]);
|
||||
andThen(() => {
|
||||
assert.equal(
|
||||
currentURL(),
|
||||
|
@ -117,7 +126,7 @@ test('/jobs/:id/:task-group should list one page of allocations for the task gro
|
|||
);
|
||||
|
||||
assert.equal(
|
||||
find('.allocations tbody tr').length,
|
||||
findAll('.allocations tbody tr').length,
|
||||
pageSize,
|
||||
'All allocations for the task group'
|
||||
);
|
||||
|
@ -126,7 +135,7 @@ test('/jobs/:id/:task-group should list one page of allocations for the task gro
|
|||
|
||||
test('each allocation should show basic information about the allocation', function(assert) {
|
||||
const allocation = allocations.sortBy('name')[0];
|
||||
const allocationRow = find('.allocations tbody tr:eq(0)');
|
||||
const allocationRow = $(findAll('.allocations tbody tr')[0]);
|
||||
|
||||
assert.equal(
|
||||
allocationRow
|
||||
|
@ -158,15 +167,21 @@ test('each allocation should show basic information about the allocation', funct
|
|||
.text()
|
||||
.trim(),
|
||||
server.db.nodes.find(allocation.nodeId).id.split('-')[0],
|
||||
'Node name'
|
||||
'Node ID'
|
||||
);
|
||||
|
||||
click(allocationRow.find('td:eq(3) a').get(0));
|
||||
|
||||
andThen(() => {
|
||||
assert.equal(currentURL(), `/nodes/${allocation.nodeId}`, 'Node links to node page');
|
||||
});
|
||||
});
|
||||
|
||||
test('each allocation should show stats about the allocation, retrieved directly from the node', function(
|
||||
assert
|
||||
) {
|
||||
const allocation = allocations.sortBy('name')[0];
|
||||
const allocationRow = find('.allocations tbody tr:eq(0)');
|
||||
const allocationRow = $(findAll('.allocations tbody tr')[0]);
|
||||
const allocStats = server.db.clientAllocationStats.find(allocation.id);
|
||||
const tasks = taskGroup.taskIds.map(id => server.db.tasks.find(id));
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import { fillIn, visit } from 'ember-native-dom-helpers';
|
||||
import { test } from 'qunit';
|
||||
import moduleForAcceptance from 'nomad-ui/tests/helpers/module-for-acceptance';
|
||||
|
||||
|
@ -22,14 +23,18 @@ test('the token form sets the token in session storage', function(assert) {
|
|||
assert.ok(window.sessionStorage.nomadTokenSecret == null, 'No token secret set');
|
||||
assert.ok(window.sessionStorage.nomadTokenAccessor == null, 'No token accessor set');
|
||||
|
||||
fillIn('.token-secret', secret);
|
||||
andThen(() => {
|
||||
fillIn('.token-secret', secret);
|
||||
});
|
||||
|
||||
andThen(() => {
|
||||
assert.equal(window.sessionStorage.nomadTokenSecret, secret, 'Token secret was set');
|
||||
assert.ok(window.sessionStorage.nomadTokenAccessor == null, 'Token accessor was not set');
|
||||
});
|
||||
|
||||
fillIn('.token-accessor', accessor);
|
||||
andThen(() => {
|
||||
fillIn('.token-accessor', accessor);
|
||||
});
|
||||
|
||||
andThen(() => {
|
||||
assert.equal(window.sessionStorage.nomadTokenAccessor, accessor, 'Token accessor was set');
|
||||
|
@ -55,7 +60,9 @@ test('the X-Nomad-Token header gets sent with requests once it is set', function
|
|||
});
|
||||
|
||||
visit('/settings/tokens');
|
||||
fillIn('.token-secret', secret);
|
||||
andThen(() => {
|
||||
fillIn('.token-secret', secret);
|
||||
});
|
||||
|
||||
visit(`/jobs/${job.id}`);
|
||||
visit(`/nodes/${node.id}`);
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import { findAll } from 'ember-native-dom-helpers';
|
||||
import { test, moduleForComponent } from 'ember-qunit';
|
||||
import hbs from 'htmlbars-inline-precompile';
|
||||
import flat from 'npm:flat';
|
||||
|
@ -42,23 +43,39 @@ test('should render the full path of key/value pair from the root of the object'
|
|||
this.render(hbs`{{attributes-table attributes=attributes}}`);
|
||||
|
||||
assert.equal(
|
||||
this.$('tbody tr:eq(0) td:eq(0)').text().trim(),
|
||||
this.$('tbody tr:eq(0) td')
|
||||
.get(0)
|
||||
.textContent.trim(),
|
||||
'key',
|
||||
'Simple row renders only the key'
|
||||
);
|
||||
assert.equal(this.$('tbody tr:eq(0) td:eq(1)').text().trim(), 'value');
|
||||
assert.equal(
|
||||
this.$('tbody tr:eq(0) td')
|
||||
.get(1)
|
||||
.textContent.trim(),
|
||||
'value'
|
||||
);
|
||||
|
||||
assert.equal(
|
||||
this.$('tbody tr:eq(8) td:eq(0)').text().trim(),
|
||||
this.$('tbody tr:eq(8) td')
|
||||
.get(0)
|
||||
.textContent.trim(),
|
||||
'so.are.deeply.nested',
|
||||
'Complex row renders the full path to the key'
|
||||
);
|
||||
assert.equal(
|
||||
this.$('tbody tr:eq(8) td:eq(0) .is-faded').text().trim(),
|
||||
this.$('tbody tr:eq(8) td:eq(0) .is-faded')
|
||||
.get(0)
|
||||
.textContent.trim(),
|
||||
'so.are.deeply.',
|
||||
'The prefix is faded to put emphasis on the attribute'
|
||||
);
|
||||
assert.equal(this.$('tbody tr:eq(8) td:eq(1)').text().trim(), 'properties');
|
||||
assert.equal(
|
||||
this.$('tbody tr:eq(8) td')
|
||||
.get(1)
|
||||
.textContent.trim(),
|
||||
'properties'
|
||||
);
|
||||
});
|
||||
|
||||
test('should render a row for key/value pairs even when the value is another object', function(
|
||||
|
@ -69,7 +86,7 @@ test('should render a row for key/value pairs even when the value is another obj
|
|||
|
||||
const countOfParentRows = countOfParentKeys(commonAttributes);
|
||||
assert.equal(
|
||||
this.$('tbody tr td[colspan="2"]').length,
|
||||
findAll('tbody tr td[colspan="2"]').length,
|
||||
countOfParentRows,
|
||||
'Each key for a nested object gets a row with no value'
|
||||
);
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import { findAll, find } from 'ember-native-dom-helpers';
|
||||
import { test, moduleForComponent } from 'ember-qunit';
|
||||
import hbs from 'htmlbars-inline-precompile';
|
||||
|
||||
|
@ -28,22 +29,22 @@ test('job field diffs', function(assert) {
|
|||
this.render(commonTemplate);
|
||||
|
||||
assert.equal(
|
||||
this.$('.diff-section-label').length,
|
||||
findAll('.diff-section-label').length,
|
||||
5,
|
||||
'A section label for each line, plus one for the group'
|
||||
);
|
||||
assert.equal(
|
||||
cleanWhitespace(this.$('.diff-section-label .diff-section-label.is-added').text()),
|
||||
cleanWhitespace(find('.diff-section-label .diff-section-label.is-added').textContent),
|
||||
'+ Added Field: "Foobar"',
|
||||
'Added field is rendered correctly'
|
||||
);
|
||||
assert.equal(
|
||||
cleanWhitespace(this.$('.diff-section-label .diff-section-label.is-edited').text()),
|
||||
cleanWhitespace(find('.diff-section-label .diff-section-label.is-edited').textContent),
|
||||
'+/- Edited Field: "256" => "512"',
|
||||
'Edited field is rendered correctly'
|
||||
);
|
||||
assert.equal(
|
||||
cleanWhitespace(this.$('.diff-section-label .diff-section-label.is-deleted').text()),
|
||||
cleanWhitespace(find('.diff-section-label .diff-section-label.is-deleted').textContent),
|
||||
'- Removed Field: "12"',
|
||||
'Removed field is rendered correctly'
|
||||
);
|
||||
|
@ -96,51 +97,51 @@ test('job object diffs', function(assert) {
|
|||
this.render(commonTemplate);
|
||||
|
||||
assert.ok(
|
||||
cleanWhitespace(this.$('.diff-section-label > .diff-section-label.is-added').text()).startsWith(
|
||||
'+ DeepConfiguration {'
|
||||
),
|
||||
cleanWhitespace(
|
||||
find('.diff-section-label > .diff-section-label.is-added').textContent
|
||||
).startsWith('+ DeepConfiguration {'),
|
||||
'Added object starts with a JSON block'
|
||||
);
|
||||
assert.ok(
|
||||
cleanWhitespace(
|
||||
this.$('.diff-section-label > .diff-section-label.is-edited').text()
|
||||
find('.diff-section-label > .diff-section-label.is-edited').textContent
|
||||
).startsWith('+/- ComplexProperty {'),
|
||||
'Edited object starts with a JSON block'
|
||||
);
|
||||
assert.ok(
|
||||
cleanWhitespace(
|
||||
this.$('.diff-section-label > .diff-section-label.is-deleted').text()
|
||||
find('.diff-section-label > .diff-section-label.is-deleted').textContent
|
||||
).startsWith('- DatedStuff {'),
|
||||
'Removed object starts with a JSON block'
|
||||
);
|
||||
|
||||
assert.ok(
|
||||
cleanWhitespace(this.$('.diff-section-label > .diff-section-label.is-added').text()).endsWith(
|
||||
'}'
|
||||
),
|
||||
cleanWhitespace(
|
||||
find('.diff-section-label > .diff-section-label.is-added').textContent
|
||||
).endsWith('}'),
|
||||
'Added object ends the JSON block'
|
||||
);
|
||||
assert.ok(
|
||||
cleanWhitespace(this.$('.diff-section-label > .diff-section-label.is-edited').text()).endsWith(
|
||||
'}'
|
||||
),
|
||||
cleanWhitespace(
|
||||
find('.diff-section-label > .diff-section-label.is-edited').textContent
|
||||
).endsWith('}'),
|
||||
'Edited object starts with a JSON block'
|
||||
);
|
||||
assert.ok(
|
||||
cleanWhitespace(this.$('.diff-section-label > .diff-section-label.is-deleted').text()).endsWith(
|
||||
'}'
|
||||
),
|
||||
cleanWhitespace(
|
||||
find('.diff-section-label > .diff-section-label.is-deleted').textContent
|
||||
).endsWith('}'),
|
||||
'Removed object ends the JSON block'
|
||||
);
|
||||
|
||||
assert.equal(
|
||||
this.$('.diff-section-label > .diff-section-label.is-added > .diff-section-label').length,
|
||||
findAll('.diff-section-label > .diff-section-label.is-added > .diff-section-label').length,
|
||||
this.get('diff').Objects[1].Objects.length + this.get('diff').Objects[1].Fields.length,
|
||||
'Edited block contains each nested field and object'
|
||||
);
|
||||
|
||||
assert.equal(
|
||||
this.$(
|
||||
findAll(
|
||||
'.diff-section-label > .diff-section-label.is-added > .diff-section-label > .diff-section-label .diff-section-table-row'
|
||||
).length,
|
||||
this.get('diff').Objects[1].Objects[0].Fields.length,
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import { findAll, find } from 'ember-native-dom-helpers';
|
||||
import { test, skip, moduleForComponent } from 'ember-qunit';
|
||||
import hbs from 'htmlbars-inline-precompile';
|
||||
|
||||
|
@ -12,7 +13,9 @@ const defaults = {
|
|||
spread: 2,
|
||||
};
|
||||
|
||||
const list100 = Array(100).fill(null).map((_, i) => i);
|
||||
const list100 = Array(100)
|
||||
.fill(null)
|
||||
.map((_, i) => i);
|
||||
|
||||
test('the source property', function(assert) {
|
||||
this.set('source', list100);
|
||||
|
@ -33,31 +36,31 @@ test('the source property', function(assert) {
|
|||
{{/list-pagination}}
|
||||
`);
|
||||
|
||||
assert.ok(!this.$('.first').length, 'On the first page, there is no first link');
|
||||
assert.ok(!this.$('.prev').length, 'On the first page, there is no prev link');
|
||||
assert.ok(!findAll('.first').length, 'On the first page, there is no first link');
|
||||
assert.ok(!findAll('.prev').length, 'On the first page, there is no prev link');
|
||||
|
||||
assert.equal(
|
||||
this.$('.link').length,
|
||||
findAll('.link').length,
|
||||
defaults.spread + 1,
|
||||
'Pages links spread to the right by the spread amount'
|
||||
);
|
||||
|
||||
for (var pageNumber = 1; pageNumber <= defaults.spread + 1; pageNumber++) {
|
||||
assert.ok(this.$(`.link.page-${pageNumber}`).length, `Page link includes ${pageNumber}`);
|
||||
assert.ok(findAll(`.link.page-${pageNumber}`).length, `Page link includes ${pageNumber}`);
|
||||
}
|
||||
|
||||
assert.ok(this.$('.next').length, 'While not on the last page, there is a next link');
|
||||
assert.ok(this.$('.last').length, 'While not on the last page, there is a last link');
|
||||
assert.ok(findAll('.next').length, 'While not on the last page, there is a next link');
|
||||
assert.ok(findAll('.last').length, 'While not on the last page, there is a last link');
|
||||
|
||||
assert.ok(
|
||||
this.$('.item').length,
|
||||
findAll('.item').length,
|
||||
defaults.size,
|
||||
`Only ${defaults.size} (the default) number of items are rendered`
|
||||
);
|
||||
|
||||
for (var item = 0; item < defaults.size; item++) {
|
||||
assert.equal(
|
||||
this.$(`.item:eq(${item})`).text(),
|
||||
findAll('.item')[item].textContent,
|
||||
item,
|
||||
'Rendered items are in the current page'
|
||||
);
|
||||
|
@ -76,7 +79,7 @@ test('the size property', function(assert) {
|
|||
`);
|
||||
|
||||
const totalPages = Math.ceil(this.get('source').length / this.get('size'));
|
||||
assert.equal(this.$('.page-info').text(), `1 of ${totalPages}`, `${totalPages} total pages`);
|
||||
assert.equal(find('.page-info').textContent, `1 of ${totalPages}`, `${totalPages} total pages`);
|
||||
});
|
||||
|
||||
test('the spread property', function(assert) {
|
||||
|
@ -144,14 +147,14 @@ test('there are no pagination links when source is less than page size', functio
|
|||
{{/list-pagination}}
|
||||
`);
|
||||
|
||||
assert.ok(!this.$('.first').length, 'No first link');
|
||||
assert.ok(!this.$('.prev').length, 'No prev link');
|
||||
assert.ok(!this.$('.next').length, 'No next link');
|
||||
assert.ok(!this.$('.last').length, 'No last link');
|
||||
assert.ok(!findAll('.first').length, 'No first link');
|
||||
assert.ok(!findAll('.prev').length, 'No prev link');
|
||||
assert.ok(!findAll('.next').length, 'No next link');
|
||||
assert.ok(!findAll('.last').length, 'No last link');
|
||||
|
||||
assert.equal(this.$('.page-info').text(), '1 of 1', 'Only one page');
|
||||
assert.equal(find('.page-info').textContent, '1 of 1', 'Only one page');
|
||||
assert.equal(
|
||||
this.$('.item').length,
|
||||
findAll('.item').length,
|
||||
this.get('source.length'),
|
||||
'Number of items equals length of source'
|
||||
);
|
||||
|
@ -180,10 +183,10 @@ test('when there are no items in source', function(assert) {
|
|||
`);
|
||||
|
||||
assert.ok(
|
||||
!this.$('.page-info, .first, .prev, .link, .next, .last, .item').length,
|
||||
!findAll('.page-info, .first, .prev, .link, .next, .last, .item').length,
|
||||
'Nothing in the yield renders'
|
||||
);
|
||||
assert.ok(this.$('.empty-state').length, 'Empty state is rendered');
|
||||
assert.ok(findAll('.empty-state').length, 'Empty state is rendered');
|
||||
});
|
||||
|
||||
// when there is less pages than the total spread amount
|
||||
|
@ -210,13 +213,13 @@ test('when there is less pages than the total spread amount', function(assert) {
|
|||
{{/list-pagination}}
|
||||
`);
|
||||
|
||||
assert.ok(this.$('.first').length, 'First page still exists');
|
||||
assert.ok(this.$('.prev').length, 'Prev page still exists');
|
||||
assert.ok(this.$('.next').length, 'Next page still exists');
|
||||
assert.ok(this.$('.last').length, 'Last page still exists');
|
||||
assert.equal(this.$('.link').length, totalPages, 'Every page gets a page link');
|
||||
assert.ok(findAll('.first').length, 'First page still exists');
|
||||
assert.ok(findAll('.prev').length, 'Prev page still exists');
|
||||
assert.ok(findAll('.next').length, 'Next page still exists');
|
||||
assert.ok(findAll('.last').length, 'Last page still exists');
|
||||
assert.equal(findAll('.link').length, totalPages, 'Every page gets a page link');
|
||||
for (var pageNumber = 1; pageNumber < totalPages; pageNumber++) {
|
||||
assert.ok(this.$(`.link.page-${pageNumber}`).length, `Page link for ${pageNumber} exists`);
|
||||
assert.ok(findAll(`.link.page-${pageNumber}`).length, `Page link for ${pageNumber} exists`);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -224,7 +227,7 @@ function testSpread(assert) {
|
|||
const { spread, currentPage } = this.getProperties('spread', 'currentPage');
|
||||
for (var pageNumber = currentPage - spread; pageNumber <= currentPage + spread; pageNumber++) {
|
||||
assert.ok(
|
||||
this.$(`.link.page-${pageNumber}`).length,
|
||||
findAll(`.link.page-${pageNumber}`).length,
|
||||
`Page links for currentPage (${currentPage}) +/- spread of ${spread} (${pageNumber})`
|
||||
);
|
||||
}
|
||||
|
@ -234,7 +237,7 @@ function testItems(assert) {
|
|||
const { currentPage, size } = this.getProperties('currentPage', 'size');
|
||||
for (var item = 0; item < size; item++) {
|
||||
assert.equal(
|
||||
this.$(`.item:eq(${item})`).text(),
|
||||
findAll('.item')[item].textContent,
|
||||
item + (currentPage - 1) * size,
|
||||
`Rendered items are in the current page, ${currentPage} (${item + (currentPage - 1) * size})`
|
||||
);
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import { findAll, find } from 'ember-native-dom-helpers';
|
||||
import { test, skip, moduleForComponent } from 'ember-qunit';
|
||||
import { faker } from 'ember-cli-mirage';
|
||||
import hbs from 'htmlbars-inline-precompile';
|
||||
|
@ -6,11 +7,13 @@ moduleForComponent('list-table', 'Integration | Component | list table', {
|
|||
integration: true,
|
||||
});
|
||||
|
||||
const commonTable = Array(10).fill(null).map(() => ({
|
||||
firstName: faker.name.firstName(),
|
||||
lastName: faker.name.lastName(),
|
||||
age: faker.random.number({ min: 18, max: 60 }),
|
||||
}));
|
||||
const commonTable = Array(10)
|
||||
.fill(null)
|
||||
.map(() => ({
|
||||
firstName: faker.name.firstName(),
|
||||
lastName: faker.name.lastName(),
|
||||
age: faker.random.number({ min: 18, max: 60 }),
|
||||
}));
|
||||
|
||||
// thead
|
||||
test('component exposes a thead contextual component', function(assert) {
|
||||
|
@ -25,12 +28,8 @@ test('component exposes a thead contextual component', function(assert) {
|
|||
{{/list-table}}
|
||||
`);
|
||||
|
||||
assert.ok(this.$('.head').length, 'Table head is rendered');
|
||||
assert.equal(
|
||||
this.$('.head').prop('tagName').toLowerCase(),
|
||||
'thead',
|
||||
'Table head is a thead element'
|
||||
);
|
||||
assert.ok(findAll('.head').length, 'Table head is rendered');
|
||||
assert.equal(find('.head').tagName.toLowerCase(), 'thead', 'Table head is a thead element');
|
||||
});
|
||||
|
||||
// tbody
|
||||
|
@ -52,22 +51,39 @@ test('component exposes a tbody contextual component', function(assert) {
|
|||
{{/list-table}}
|
||||
`);
|
||||
|
||||
assert.ok(this.$('.body').length, 'Table body is rendered');
|
||||
assert.equal(
|
||||
this.$('.body').prop('tagName').toLowerCase(),
|
||||
'tbody',
|
||||
'Table body is a tbody element'
|
||||
);
|
||||
assert.ok(findAll('.body').length, 'Table body is rendered');
|
||||
assert.equal(find('.body').tagName.toLowerCase(), 'tbody', 'Table body is a tbody element');
|
||||
|
||||
assert.equal(this.$('.item').length, this.get('source.length'), 'Each item gets its own row');
|
||||
assert.equal(findAll('.item').length, this.get('source.length'), 'Each item gets its own row');
|
||||
|
||||
// list-table is not responsible for sorting, only dispatching sort events. The table is still
|
||||
// rendered in index-order.
|
||||
this.get('source').forEach((item, index) => {
|
||||
const $item = this.$(`.item:eq(${index})`);
|
||||
assert.equal($item.find('td:eq(0)').text().trim(), item.firstName, 'First name');
|
||||
assert.equal($item.find('td:eq(1)').text().trim(), item.lastName, 'Last name');
|
||||
assert.equal($item.find('td:eq(2)').text().trim(), item.age, 'Age');
|
||||
assert.equal(
|
||||
$item
|
||||
.find('td:eq(0)')
|
||||
.text()
|
||||
.trim(),
|
||||
item.firstName,
|
||||
'First name'
|
||||
);
|
||||
assert.equal(
|
||||
$item
|
||||
.find('td:eq(1)')
|
||||
.text()
|
||||
.trim(),
|
||||
item.lastName,
|
||||
'Last name'
|
||||
);
|
||||
assert.equal(
|
||||
$item
|
||||
.find('td:eq(2)')
|
||||
.text()
|
||||
.trim(),
|
||||
item.age,
|
||||
'Age'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -3103,6 +3103,13 @@ ember-moment@^7.3.1:
|
|||
ember-getowner-polyfill "^2.0.1"
|
||||
ember-macro-helpers "^0.15.1"
|
||||
|
||||
ember-native-dom-helpers@^0.5.4:
|
||||
version "0.5.4"
|
||||
resolved "https://registry.yarnpkg.com/ember-native-dom-helpers/-/ember-native-dom-helpers-0.5.4.tgz#0bc1506a643fb7adc0abf1d09c44a7914459296b"
|
||||
dependencies:
|
||||
broccoli-funnel "^1.1.0"
|
||||
ember-cli-babel "^6.6.0"
|
||||
|
||||
ember-qunit@^2.1.3:
|
||||
version "2.2.0"
|
||||
resolved "https://registry.yarnpkg.com/ember-qunit/-/ember-qunit-2.2.0.tgz#3cdf400031c93a38de781a7304819738753b7f99"
|
||||
|
|
Loading…
Reference in New Issue