2018-05-13 03:01:51 +00:00
|
|
|
import { assign } from '@ember/polyfills';
|
2017-12-15 21:39:18 +00:00
|
|
|
import $ from 'jquery';
|
2017-09-26 07:47:16 +00:00
|
|
|
import { click, find, findAll, currentURL, visit } from 'ember-native-dom-helpers';
|
2017-09-19 14:47:10 +00:00
|
|
|
import { test } from 'qunit';
|
|
|
|
import moduleForAcceptance from 'nomad-ui/tests/helpers/module-for-acceptance';
|
2017-10-17 01:47:25 +00:00
|
|
|
import { formatBytes } from 'nomad-ui/helpers/format-bytes';
|
2017-11-30 23:08:31 +00:00
|
|
|
import moment from 'moment';
|
2017-09-19 14:47:10 +00:00
|
|
|
|
|
|
|
let node;
|
|
|
|
|
|
|
|
moduleForAcceptance('Acceptance | client detail', {
|
|
|
|
beforeEach() {
|
|
|
|
server.create('node', 'forceIPv4');
|
|
|
|
node = server.db.nodes[0];
|
|
|
|
|
|
|
|
// Related models
|
|
|
|
server.create('agent');
|
|
|
|
server.create('job', { createAllocations: false });
|
|
|
|
server.createList('allocation', 3, { nodeId: node.id });
|
|
|
|
},
|
|
|
|
});
|
|
|
|
|
2018-03-11 17:44:27 +00:00
|
|
|
test('/clients/:id should have a breadcrumb trail linking back to clients', function(assert) {
|
2017-10-28 01:23:41 +00:00
|
|
|
visit(`/clients/${node.id}`);
|
2017-10-06 03:11:17 +00:00
|
|
|
|
|
|
|
andThen(() => {
|
|
|
|
assert.equal(
|
2018-05-13 03:01:51 +00:00
|
|
|
find('[data-test-breadcrumb="clients"]').textContent.trim(),
|
2017-12-20 01:25:35 +00:00
|
|
|
'Clients',
|
|
|
|
'First breadcrumb says clients'
|
|
|
|
);
|
|
|
|
assert.equal(
|
2018-05-13 03:01:51 +00:00
|
|
|
find('[data-test-breadcrumb="client"]').textContent.trim(),
|
2017-10-06 03:11:17 +00:00
|
|
|
node.id.split('-')[0],
|
|
|
|
'Second breadcrumb says the node short id'
|
|
|
|
);
|
|
|
|
});
|
|
|
|
|
|
|
|
andThen(() => {
|
2018-01-05 20:59:36 +00:00
|
|
|
click(find('[data-test-breadcrumb="clients"]'));
|
2017-10-06 03:11:17 +00:00
|
|
|
});
|
|
|
|
|
2017-09-19 14:47:10 +00:00
|
|
|
andThen(() => {
|
2017-10-28 01:23:41 +00:00
|
|
|
assert.equal(currentURL(), '/clients', 'First breadcrumb links back to clients');
|
2017-09-19 14:47:10 +00:00
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2017-10-28 01:23:41 +00:00
|
|
|
test('/clients/:id should list immediate details for the node in the title', function(assert) {
|
|
|
|
visit(`/clients/${node.id}`);
|
2017-10-06 03:11:17 +00:00
|
|
|
|
|
|
|
andThen(() => {
|
2018-01-05 20:59:36 +00:00
|
|
|
assert.ok(find('[data-test-title]').textContent.includes(node.name), 'Title includes name');
|
|
|
|
assert.ok(find('[data-test-title]').textContent.includes(node.id), 'Title includes id');
|
|
|
|
assert.ok(find(`[data-test-node-status="${node.status}"]`), 'Title includes status light');
|
2017-10-06 03:11:17 +00:00
|
|
|
});
|
2017-09-19 14:47:10 +00:00
|
|
|
});
|
|
|
|
|
2017-10-28 01:23:41 +00:00
|
|
|
test('/clients/:id should list additional detail for the node below the title', function(assert) {
|
|
|
|
visit(`/clients/${node.id}`);
|
2017-10-06 03:11:17 +00:00
|
|
|
|
|
|
|
andThen(() => {
|
2018-05-13 03:01:51 +00:00
|
|
|
assert.ok(
|
|
|
|
find('.inline-definitions .pair')
|
|
|
|
.textContent.trim()
|
|
|
|
.includes(node.status),
|
2017-10-06 03:11:17 +00:00
|
|
|
'Status is in additional details'
|
|
|
|
);
|
|
|
|
assert.ok(
|
2018-01-05 20:59:36 +00:00
|
|
|
$('[data-test-status-definition] .status-text').hasClass(`node-${node.status}`),
|
2017-10-06 03:11:17 +00:00
|
|
|
'Status is decorated with a status class'
|
|
|
|
);
|
2018-05-13 03:01:51 +00:00
|
|
|
assert.ok(
|
|
|
|
find('[data-test-address-definition]')
|
|
|
|
.textContent.trim()
|
|
|
|
.includes(node.httpAddr),
|
2018-03-11 17:54:56 +00:00
|
|
|
'Address is in additional details'
|
2017-10-06 03:11:17 +00:00
|
|
|
);
|
2018-05-13 03:01:51 +00:00
|
|
|
assert.ok(
|
|
|
|
find('[data-test-datacenter-definition]')
|
|
|
|
.textContent.trim()
|
|
|
|
.includes(node.datacenter),
|
2017-10-06 03:11:17 +00:00
|
|
|
'Datacenter is in additional details'
|
|
|
|
);
|
|
|
|
});
|
2017-09-19 14:47:10 +00:00
|
|
|
});
|
|
|
|
|
2017-10-28 01:23:41 +00:00
|
|
|
test('/clients/:id should list all allocations on the node', function(assert) {
|
2017-09-19 14:47:10 +00:00
|
|
|
const allocationsCount = server.db.allocations.where({ nodeId: node.id }).length;
|
2017-10-06 03:11:17 +00:00
|
|
|
|
2017-10-28 01:23:41 +00:00
|
|
|
visit(`/clients/${node.id}`);
|
2017-10-06 03:11:17 +00:00
|
|
|
|
|
|
|
andThen(() => {
|
|
|
|
assert.equal(
|
2018-01-05 20:59:36 +00:00
|
|
|
findAll('[data-test-allocation]').length,
|
2017-10-06 03:11:17 +00:00
|
|
|
allocationsCount,
|
|
|
|
`Allocations table lists all ${allocationsCount} associated allocations`
|
|
|
|
);
|
|
|
|
});
|
2017-09-19 14:47:10 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
test('each allocation should have high-level details for the allocation', function(assert) {
|
|
|
|
const allocation = server.db.allocations
|
|
|
|
.where({ nodeId: node.id })
|
|
|
|
.sortBy('modifyIndex')
|
|
|
|
.reverse()[0];
|
|
|
|
|
|
|
|
const allocStats = server.db.clientAllocationStats.find(allocation.id);
|
|
|
|
const taskGroup = server.db.taskGroups.findBy({
|
|
|
|
name: allocation.taskGroup,
|
|
|
|
jobId: allocation.jobId,
|
|
|
|
});
|
|
|
|
|
|
|
|
const tasks = taskGroup.taskIds.map(id => server.db.tasks.find(id));
|
2017-10-17 01:47:25 +00:00
|
|
|
const cpuUsed = tasks.reduce((sum, task) => sum + task.Resources.CPU, 0);
|
|
|
|
const memoryUsed = tasks.reduce((sum, task) => sum + task.Resources.MemoryMB, 0);
|
2017-09-19 14:47:10 +00:00
|
|
|
|
2017-10-28 01:23:41 +00:00
|
|
|
visit(`/clients/${node.id}`);
|
2017-10-06 03:11:17 +00:00
|
|
|
|
|
|
|
andThen(() => {
|
2018-01-05 20:59:36 +00:00
|
|
|
const allocationRow = $(find('[data-test-allocation]'));
|
2017-10-06 03:11:17 +00:00
|
|
|
assert.equal(
|
|
|
|
allocationRow
|
2018-01-05 20:59:36 +00:00
|
|
|
.find('[data-test-short-id]')
|
2017-10-06 03:11:17 +00:00
|
|
|
.text()
|
|
|
|
.trim(),
|
|
|
|
allocation.id.split('-')[0],
|
|
|
|
'Allocation short ID'
|
|
|
|
);
|
|
|
|
assert.equal(
|
|
|
|
allocationRow
|
2018-01-05 20:59:36 +00:00
|
|
|
.find('[data-test-modify-time]')
|
2017-10-06 03:11:17 +00:00
|
|
|
.text()
|
|
|
|
.trim(),
|
2017-11-30 23:08:31 +00:00
|
|
|
moment(allocation.modifyTime / 1000000).format('MM/DD HH:mm:ss'),
|
|
|
|
'Allocation modify time'
|
2017-10-18 02:19:02 +00:00
|
|
|
);
|
|
|
|
assert.equal(
|
|
|
|
allocationRow
|
2018-01-05 20:59:36 +00:00
|
|
|
.find('[data-test-name]')
|
2017-10-18 02:19:02 +00:00
|
|
|
.text()
|
|
|
|
.trim(),
|
2017-10-06 03:11:17 +00:00
|
|
|
allocation.name,
|
|
|
|
'Allocation name'
|
|
|
|
);
|
|
|
|
assert.equal(
|
|
|
|
allocationRow
|
2018-01-05 20:59:36 +00:00
|
|
|
.find('[data-test-client-status]')
|
2017-10-06 03:11:17 +00:00
|
|
|
.text()
|
|
|
|
.trim(),
|
|
|
|
allocation.clientStatus,
|
|
|
|
'Client status'
|
|
|
|
);
|
2018-01-05 20:59:36 +00:00
|
|
|
assert.equal(
|
2017-10-06 03:11:17 +00:00
|
|
|
allocationRow
|
2018-01-05 20:59:36 +00:00
|
|
|
.find('[data-test-job]')
|
2017-10-06 03:11:17 +00:00
|
|
|
.text()
|
2018-01-05 20:59:36 +00:00
|
|
|
.trim(),
|
|
|
|
server.db.jobs.find(allocation.jobId).name,
|
2017-10-06 03:11:17 +00:00
|
|
|
'Job name'
|
|
|
|
);
|
|
|
|
assert.ok(
|
|
|
|
allocationRow
|
2018-01-05 20:59:36 +00:00
|
|
|
.find('[data-test-task-group]')
|
2017-10-06 03:11:17 +00:00
|
|
|
.text()
|
|
|
|
.includes(allocation.taskGroup),
|
|
|
|
'Task group name'
|
|
|
|
);
|
2017-10-18 19:29:33 +00:00
|
|
|
assert.ok(
|
2017-10-06 03:11:17 +00:00
|
|
|
allocationRow
|
2018-01-05 20:59:36 +00:00
|
|
|
.find('[data-test-job-version]')
|
2017-10-06 03:11:17 +00:00
|
|
|
.text()
|
2017-10-18 19:29:33 +00:00
|
|
|
.includes(allocation.jobVersion),
|
|
|
|
'Job Version'
|
|
|
|
);
|
|
|
|
assert.equal(
|
|
|
|
allocationRow
|
2018-01-05 20:59:36 +00:00
|
|
|
.find('[data-test-cpu]')
|
2017-10-18 19:29:33 +00:00
|
|
|
.text()
|
2017-10-06 03:11:17 +00:00
|
|
|
.trim(),
|
2017-10-19 17:43:33 +00:00
|
|
|
Math.floor(allocStats.resourceUsage.CpuStats.TotalTicks) / cpuUsed,
|
2017-10-06 03:11:17 +00:00
|
|
|
'CPU %'
|
|
|
|
);
|
2017-10-17 01:47:25 +00:00
|
|
|
assert.equal(
|
2018-01-05 20:59:36 +00:00
|
|
|
allocationRow.find('[data-test-cpu] .tooltip').attr('aria-label'),
|
2017-10-17 01:47:25 +00:00
|
|
|
`${Math.floor(allocStats.resourceUsage.CpuStats.TotalTicks)} / ${cpuUsed} MHz`,
|
|
|
|
'Detailed CPU information is in a tooltip'
|
|
|
|
);
|
2017-10-06 03:11:17 +00:00
|
|
|
assert.equal(
|
|
|
|
allocationRow
|
2018-01-05 20:59:36 +00:00
|
|
|
.find('[data-test-mem]')
|
2017-10-06 03:11:17 +00:00
|
|
|
.text()
|
|
|
|
.trim(),
|
2017-10-17 01:47:25 +00:00
|
|
|
allocStats.resourceUsage.MemoryStats.RSS / 1024 / 1024 / memoryUsed,
|
2017-10-06 03:11:17 +00:00
|
|
|
'Memory used'
|
|
|
|
);
|
2017-10-17 01:47:25 +00:00
|
|
|
assert.equal(
|
2018-01-05 20:59:36 +00:00
|
|
|
allocationRow.find('[data-test-mem] .tooltip').attr('aria-label'),
|
2017-10-17 01:47:25 +00:00
|
|
|
`${formatBytes([allocStats.resourceUsage.MemoryStats.RSS])} / ${memoryUsed} MiB`,
|
|
|
|
'Detailed memory information is in a tooltip'
|
|
|
|
);
|
2017-10-06 03:11:17 +00:00
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2018-02-07 02:52:16 +00:00
|
|
|
test('each allocation should show job information even if the job is incomplete and already in the store', function(assert) {
|
2017-10-28 01:23:41 +00:00
|
|
|
// First, visit clients to load the allocations for each visible node.
|
2017-10-06 03:11:17 +00:00
|
|
|
// Don't load the job belongsTo of the allocation! Leave it unfulfilled.
|
|
|
|
|
2017-10-28 01:23:41 +00:00
|
|
|
visit('/clients');
|
2017-10-06 03:11:17 +00:00
|
|
|
|
|
|
|
// Then, visit jobs to load all jobs, which should implicitly fulfill
|
|
|
|
// the job belongsTo of each allocation pointed at each job.
|
|
|
|
|
|
|
|
visit('/jobs');
|
|
|
|
|
|
|
|
// Finally, visit a node to assert that the job name and task group name are
|
|
|
|
// present. This will require reloading the job, since task groups aren't a
|
|
|
|
// part of the jobs list response.
|
|
|
|
|
2017-10-28 01:23:41 +00:00
|
|
|
visit(`/clients/${node.id}`);
|
2017-10-06 03:11:17 +00:00
|
|
|
|
|
|
|
andThen(() => {
|
2018-01-05 20:59:36 +00:00
|
|
|
const allocationRow = $(find('[data-test-allocation]'));
|
2017-10-06 03:11:17 +00:00
|
|
|
const allocation = server.db.allocations
|
|
|
|
.where({ nodeId: node.id })
|
|
|
|
.sortBy('modifyIndex')
|
|
|
|
.reverse()[0];
|
|
|
|
|
|
|
|
assert.ok(
|
|
|
|
allocationRow
|
2018-01-05 20:59:36 +00:00
|
|
|
.find('[data-test-job]')
|
2017-10-06 03:11:17 +00:00
|
|
|
.text()
|
|
|
|
.includes(server.db.jobs.find(allocation.jobId).name),
|
|
|
|
'Job name'
|
|
|
|
);
|
|
|
|
assert.ok(
|
|
|
|
allocationRow
|
2018-01-05 20:59:36 +00:00
|
|
|
.find('[data-test-task-group]')
|
2017-10-06 03:11:17 +00:00
|
|
|
.text()
|
|
|
|
.includes(allocation.taskGroup),
|
|
|
|
'Task group name'
|
|
|
|
);
|
|
|
|
});
|
2017-09-19 14:47:10 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
test('each allocation should link to the allocation detail page', function(assert) {
|
|
|
|
const allocation = server.db.allocations
|
|
|
|
.where({ nodeId: node.id })
|
|
|
|
.sortBy('modifyIndex')
|
|
|
|
.reverse()[0];
|
|
|
|
|
2017-10-28 01:23:41 +00:00
|
|
|
visit(`/clients/${node.id}`);
|
2017-10-06 03:11:17 +00:00
|
|
|
|
|
|
|
andThen(() => {
|
2018-01-05 20:59:36 +00:00
|
|
|
click('[data-test-short-id] a');
|
2017-10-06 03:11:17 +00:00
|
|
|
});
|
2017-09-19 14:47:10 +00:00
|
|
|
|
|
|
|
andThen(() => {
|
|
|
|
assert.equal(
|
|
|
|
currentURL(),
|
|
|
|
`/allocations/${allocation.id}`,
|
|
|
|
'Allocation rows link to allocation detail pages'
|
|
|
|
);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
test('each allocation should link to the job the allocation belongs to', function(assert) {
|
2017-10-28 01:23:41 +00:00
|
|
|
visit(`/clients/${node.id}`);
|
2017-10-06 03:11:17 +00:00
|
|
|
|
2017-09-19 14:47:10 +00:00
|
|
|
const allocation = server.db.allocations.where({ nodeId: node.id })[0];
|
|
|
|
const job = server.db.jobs.find(allocation.jobId);
|
2017-10-06 03:11:17 +00:00
|
|
|
|
|
|
|
andThen(() => {
|
2018-01-05 20:59:36 +00:00
|
|
|
click('[data-test-job]');
|
2017-10-06 03:11:17 +00:00
|
|
|
});
|
2017-09-19 14:47:10 +00:00
|
|
|
|
|
|
|
andThen(() => {
|
|
|
|
assert.equal(
|
|
|
|
currentURL(),
|
|
|
|
`/jobs/${job.id}`,
|
|
|
|
'Allocation rows link to the job detail page for the allocation'
|
|
|
|
);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2017-10-28 01:23:41 +00:00
|
|
|
test('/clients/:id should list all attributes for the node', function(assert) {
|
|
|
|
visit(`/clients/${node.id}`);
|
2017-10-06 03:11:17 +00:00
|
|
|
|
|
|
|
andThen(() => {
|
2018-01-05 20:59:36 +00:00
|
|
|
assert.ok(find('[data-test-attributes]'), 'Attributes table is on the page');
|
2017-10-06 03:11:17 +00:00
|
|
|
});
|
2017-09-19 14:47:10 +00:00
|
|
|
});
|
2017-09-29 00:05:41 +00:00
|
|
|
|
2018-02-07 02:52:16 +00:00
|
|
|
test('/clients/:id lists all meta attributes', function(assert) {
|
|
|
|
node = server.create('node', 'forceIPv4', 'withMeta');
|
|
|
|
|
|
|
|
visit(`/clients/${node.id}`);
|
|
|
|
|
|
|
|
andThen(() => {
|
|
|
|
assert.ok(find('[data-test-meta]'), 'Meta attributes table is on the page');
|
|
|
|
assert.notOk(find('[data-test-empty-meta-message]'), 'Meta attributes is not empty');
|
2018-02-27 00:35:41 +00:00
|
|
|
|
|
|
|
const firstMetaKey = Object.keys(node.meta)[0];
|
|
|
|
assert.equal(
|
|
|
|
find('[data-test-meta] [data-test-key]').textContent.trim(),
|
|
|
|
firstMetaKey,
|
|
|
|
'Meta attributes for the node are bound to the attributes table'
|
|
|
|
);
|
|
|
|
assert.equal(
|
|
|
|
find('[data-test-meta] [data-test-value]').textContent.trim(),
|
|
|
|
node.meta[firstMetaKey],
|
|
|
|
'Meta attributes for the node are bound to the attributes table'
|
|
|
|
);
|
2018-02-07 02:52:16 +00:00
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
test('/clients/:id shows an empty message when there is no meta data', function(assert) {
|
|
|
|
visit(`/clients/${node.id}`);
|
|
|
|
|
|
|
|
andThen(() => {
|
|
|
|
assert.notOk(find('[data-test-meta]'), 'Meta attributes table is not on the page');
|
|
|
|
assert.ok(find('[data-test-empty-meta-message]'), 'Meta attributes is empty');
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
test('when the node is not found, an error message is shown, but the URL persists', function(assert) {
|
2017-10-28 01:23:41 +00:00
|
|
|
visit('/clients/not-a-real-node');
|
2017-09-29 00:05:41 +00:00
|
|
|
|
|
|
|
andThen(() => {
|
|
|
|
assert.equal(
|
|
|
|
server.pretender.handledRequests.findBy('status', 404).url,
|
|
|
|
'/v1/node/not-a-real-node',
|
2018-03-12 18:26:37 +00:00
|
|
|
'A request to the nonexistent node is made'
|
2017-09-29 00:05:41 +00:00
|
|
|
);
|
2017-10-28 01:23:41 +00:00
|
|
|
assert.equal(currentURL(), '/clients/not-a-real-node', 'The URL persists');
|
2018-01-05 20:59:36 +00:00
|
|
|
assert.ok(find('[data-test-error]'), 'Error message is shown');
|
2017-09-29 00:05:41 +00:00
|
|
|
assert.equal(
|
2018-05-13 03:01:51 +00:00
|
|
|
find('[data-test-error-title]').textContent.trim(),
|
2017-09-29 00:05:41 +00:00
|
|
|
'Not Found',
|
|
|
|
'Error message is for 404'
|
|
|
|
);
|
|
|
|
});
|
|
|
|
});
|
2018-05-13 03:01:51 +00:00
|
|
|
|
|
|
|
test('/clients/:id shows the recent events list', function(assert) {
|
|
|
|
visit(`/clients/${node.id}`);
|
|
|
|
|
|
|
|
andThen(() => {
|
|
|
|
assert.ok(find('[data-test-client-events]'), 'Client events section exists');
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
test('each node event shows basic node event information', function(assert) {
|
|
|
|
const event = server.db.nodeEvents
|
|
|
|
.where({ nodeId: node.id })
|
|
|
|
.sortBy('time')
|
|
|
|
.reverse()[0];
|
|
|
|
|
|
|
|
visit(`/clients/${node.id}`);
|
|
|
|
|
|
|
|
andThen(() => {
|
|
|
|
const eventRow = $(find('[data-test-client-event]'));
|
|
|
|
assert.equal(
|
|
|
|
eventRow
|
|
|
|
.find('[data-test-client-event-time]')
|
|
|
|
.text()
|
|
|
|
.trim(),
|
|
|
|
moment(event.time).format('MM/DD/YY HH:mm:ss'),
|
|
|
|
'Event timestamp'
|
|
|
|
);
|
|
|
|
assert.equal(
|
|
|
|
eventRow
|
|
|
|
.find('[data-test-client-event-subsystem]')
|
|
|
|
.text()
|
|
|
|
.trim(),
|
|
|
|
event.subsystem,
|
|
|
|
'Event subsystem'
|
|
|
|
);
|
|
|
|
assert.equal(
|
|
|
|
eventRow
|
|
|
|
.find('[data-test-client-event-message]')
|
|
|
|
.text()
|
|
|
|
.trim(),
|
|
|
|
event.message,
|
|
|
|
'Event message'
|
|
|
|
);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
test('/clients/:id shows the driver status of every driver for the node', function(assert) {
|
|
|
|
// Set the drivers up so health and detection is well tested
|
|
|
|
const nodeDrivers = node.drivers;
|
|
|
|
const undetectedDriver = 'raw_exec';
|
|
|
|
|
|
|
|
Object.values(nodeDrivers).forEach(driver => {
|
|
|
|
driver.Detected = true;
|
|
|
|
});
|
|
|
|
|
|
|
|
nodeDrivers[undetectedDriver].Detected = false;
|
|
|
|
node.drivers = nodeDrivers;
|
|
|
|
|
|
|
|
const drivers = Object.keys(node.drivers)
|
|
|
|
.map(driverName => assign({ Name: driverName }, node.drivers[driverName]))
|
|
|
|
.sortBy('Name');
|
|
|
|
|
|
|
|
assert.ok(drivers.length > 0, 'Node has drivers');
|
|
|
|
|
|
|
|
visit(`/clients/${node.id}`);
|
|
|
|
|
|
|
|
andThen(() => {
|
|
|
|
const driverRows = findAll('[data-test-driver-status] [data-test-accordion-head]');
|
|
|
|
|
|
|
|
drivers.forEach((driver, index) => {
|
|
|
|
const driverRow = $(driverRows[index]);
|
|
|
|
|
|
|
|
assert.equal(
|
|
|
|
driverRow
|
|
|
|
.find('[data-test-name]')
|
|
|
|
.text()
|
|
|
|
.trim(),
|
|
|
|
driver.Name,
|
|
|
|
`${driver.Name}: Name is correct`
|
|
|
|
);
|
|
|
|
assert.equal(
|
|
|
|
driverRow
|
|
|
|
.find('[data-test-detected]')
|
|
|
|
.text()
|
|
|
|
.trim(),
|
|
|
|
driver.Detected ? 'Yes' : 'No',
|
|
|
|
`${driver.Name}: Detection is correct`
|
|
|
|
);
|
|
|
|
assert.equal(
|
|
|
|
driverRow
|
|
|
|
.find('[data-test-last-updated]')
|
|
|
|
.text()
|
|
|
|
.trim(),
|
|
|
|
moment(driver.UpdateTime).fromNow(),
|
|
|
|
`${driver.Name}: Last updated shows time since now`
|
|
|
|
);
|
|
|
|
|
|
|
|
if (driver.Name === undetectedDriver) {
|
|
|
|
assert.notOk(
|
|
|
|
driverRow.find('[data-test-health]').length,
|
|
|
|
`${driver.Name}: No health for the undetected driver`
|
|
|
|
);
|
|
|
|
} else {
|
|
|
|
assert.equal(
|
|
|
|
driverRow
|
|
|
|
.find('[data-test-health]')
|
|
|
|
.text()
|
|
|
|
.trim(),
|
|
|
|
driver.Healthy ? 'Healthy' : 'Unhealthy',
|
|
|
|
`${driver.Name}: Health is correct`
|
|
|
|
);
|
|
|
|
assert.ok(
|
|
|
|
driverRow
|
|
|
|
.find('[data-test-health] .color-swatch')
|
|
|
|
.hasClass(driver.Healthy ? 'running' : 'failed'),
|
|
|
|
`${driver.Name}: Swatch with correct class is shown`
|
|
|
|
);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
test('each driver can be opened to see a message and attributes', function(assert) {
|
|
|
|
// Only detected drivers can be expanded
|
|
|
|
const nodeDrivers = node.drivers;
|
|
|
|
Object.values(nodeDrivers).forEach(driver => {
|
|
|
|
driver.Detected = true;
|
|
|
|
});
|
|
|
|
node.drivers = nodeDrivers;
|
|
|
|
|
|
|
|
const driver = Object.keys(node.drivers)
|
|
|
|
.map(driverName => assign({ Name: driverName }, node.drivers[driverName]))
|
|
|
|
.sortBy('Name')[0];
|
|
|
|
|
|
|
|
visit(`/clients/${node.id}`);
|
|
|
|
|
|
|
|
andThen(() => {
|
|
|
|
const driverBody = $(find('[data-test-driver-status] [data-test-accordion-body]'));
|
|
|
|
assert.notOk(
|
|
|
|
driverBody.find('[data-test-health-description]').length,
|
|
|
|
'Driver health description is not shown'
|
|
|
|
);
|
|
|
|
assert.notOk(
|
|
|
|
driverBody.find('[data-test-driver-attributes]').length,
|
|
|
|
'Driver attributes section is not shown'
|
|
|
|
);
|
|
|
|
click('[data-test-driver-status] [data-test-accordion-toggle]');
|
|
|
|
});
|
|
|
|
|
|
|
|
andThen(() => {
|
|
|
|
const driverBody = $(find('[data-test-driver-status] [data-test-accordion-body]'));
|
|
|
|
assert.equal(
|
|
|
|
driverBody
|
|
|
|
.find('[data-test-health-description]')
|
|
|
|
.text()
|
|
|
|
.trim(),
|
|
|
|
driver.HealthDescription,
|
|
|
|
'Driver health description is now shown'
|
|
|
|
);
|
|
|
|
assert.ok(
|
|
|
|
driverBody.find('[data-test-driver-attributes]').length,
|
|
|
|
'Driver attributes section is now shown'
|
|
|
|
);
|
|
|
|
});
|
|
|
|
});
|