UI/d3 DOM cleanup hover issue (#14493)
* fix duplicate rendering of chart elements * organize SVG char elements into groups, give data-test attrs * update tests * tweak mirage * add fake client counting start date * fix test * add waitUntil * adds changelog * add second waituntil
This commit is contained in:
parent
0dfabe7ade
commit
a003d9875e
|
@ -0,0 +1,3 @@
|
||||||
|
```release-note:bug
|
||||||
|
ui: Fixes horizontal bar chart hover issue when filtering namespaces and mounts
|
||||||
|
```
|
|
@ -69,21 +69,26 @@ export default class HorizontalBarChart extends Component {
|
||||||
|
|
||||||
let chartSvg = select(element);
|
let chartSvg = select(element);
|
||||||
chartSvg.attr('width', '100%').attr('viewBox', `0 0 564 ${(dataset.length + 1) * LINE_HEIGHT}`);
|
chartSvg.attr('width', '100%').attr('viewBox', `0 0 564 ${(dataset.length + 1) * LINE_HEIGHT}`);
|
||||||
// chartSvg.attr('viewBox', `0 0 700 300`);
|
|
||||||
|
|
||||||
let groups = chartSvg
|
let dataBarGroup = chartSvg
|
||||||
.selectAll('g')
|
.selectAll('g')
|
||||||
.remove()
|
.remove()
|
||||||
.exit()
|
.exit()
|
||||||
.data(stackedData)
|
.data(stackedData)
|
||||||
.enter()
|
.enter()
|
||||||
.append('g')
|
.append('g')
|
||||||
|
.attr('data-test-group', (d) => `${d.key}`)
|
||||||
// shifts chart to accommodate y-axis legend
|
// shifts chart to accommodate y-axis legend
|
||||||
.attr('transform', `translate(${CHART_MARGIN.left}, ${CHART_MARGIN.top})`)
|
.attr('transform', `translate(${CHART_MARGIN.left}, ${CHART_MARGIN.top})`)
|
||||||
.style('fill', (d, i) => LIGHT_AND_DARK_BLUE[i]);
|
.style('fill', (d, i) => LIGHT_AND_DARK_BLUE[i]);
|
||||||
|
|
||||||
let yAxis = axisLeft(yScale).tickSize(0);
|
let yAxis = axisLeft(yScale).tickSize(0);
|
||||||
yAxis(chartSvg.append('g').attr('transform', `translate(${CHART_MARGIN.left}, ${CHART_MARGIN.top})`));
|
|
||||||
|
let yLabelsGroup = chartSvg
|
||||||
|
.append('g')
|
||||||
|
.attr('data-test-group', 'y-labels')
|
||||||
|
.attr('transform', `translate(${CHART_MARGIN.left}, ${CHART_MARGIN.top})`);
|
||||||
|
yAxis(yLabelsGroup);
|
||||||
|
|
||||||
chartSvg.select('.domain').remove();
|
chartSvg.select('.domain').remove();
|
||||||
|
|
||||||
|
@ -94,8 +99,10 @@ export default class HorizontalBarChart extends Component {
|
||||||
|
|
||||||
chartSvg.selectAll('.tick text').call(truncate);
|
chartSvg.selectAll('.tick text').call(truncate);
|
||||||
|
|
||||||
groups
|
dataBarGroup
|
||||||
.selectAll('rect')
|
.selectAll('rect')
|
||||||
|
.remove()
|
||||||
|
.exit()
|
||||||
// iterate through the stacked data and chart respectively
|
// iterate through the stacked data and chart respectively
|
||||||
.data((stackedData) => stackedData)
|
.data((stackedData) => stackedData)
|
||||||
.enter()
|
.enter()
|
||||||
|
@ -109,8 +116,12 @@ export default class HorizontalBarChart extends Component {
|
||||||
.attr('rx', 3)
|
.attr('rx', 3)
|
||||||
.attr('ry', 3);
|
.attr('ry', 3);
|
||||||
|
|
||||||
let actionBars = chartSvg
|
let actionBarGroup = chartSvg.append('g').attr('data-test-group', 'action-bars');
|
||||||
|
|
||||||
|
let actionBars = actionBarGroup
|
||||||
.selectAll('.action-bar')
|
.selectAll('.action-bar')
|
||||||
|
.remove()
|
||||||
|
.exit()
|
||||||
.data(dataset)
|
.data(dataset)
|
||||||
.enter()
|
.enter()
|
||||||
.append('rect')
|
.append('rect')
|
||||||
|
@ -124,8 +135,12 @@ export default class HorizontalBarChart extends Component {
|
||||||
.style('opacity', '0')
|
.style('opacity', '0')
|
||||||
.style('mix-blend-mode', 'multiply');
|
.style('mix-blend-mode', 'multiply');
|
||||||
|
|
||||||
let yLegendBars = chartSvg
|
let labelActionBarGroup = chartSvg.append('g').attr('data-test-group', 'label-action-bars');
|
||||||
.selectAll('.label-bar')
|
|
||||||
|
let labelActionBar = labelActionBarGroup
|
||||||
|
.selectAll('.label-action-bar')
|
||||||
|
.remove()
|
||||||
|
.exit()
|
||||||
.data(dataset)
|
.data(dataset)
|
||||||
.enter()
|
.enter()
|
||||||
.append('rect')
|
.append('rect')
|
||||||
|
@ -173,10 +188,10 @@ export default class HorizontalBarChart extends Component {
|
||||||
});
|
});
|
||||||
|
|
||||||
// MOUSE EVENTS FOR Y-AXIS LABELS
|
// MOUSE EVENTS FOR Y-AXIS LABELS
|
||||||
yLegendBars
|
labelActionBar
|
||||||
.on('mouseover', (data) => {
|
.on('mouseover', (data) => {
|
||||||
if (data.label.length >= CHAR_LIMIT) {
|
if (data.label.length >= CHAR_LIMIT) {
|
||||||
let hoveredElement = yLegendBars.filter((bar) => bar.label === data.label).node();
|
let hoveredElement = labelActionBar.filter((bar) => bar.label === data.label).node();
|
||||||
this.tooltipTarget = hoveredElement;
|
this.tooltipTarget = hoveredElement;
|
||||||
this.isLabel = true;
|
this.isLabel = true;
|
||||||
this.tooltipText = data.label;
|
this.tooltipText = data.label;
|
||||||
|
@ -208,10 +223,13 @@ export default class HorizontalBarChart extends Component {
|
||||||
.style('opacity', '0');
|
.style('opacity', '0');
|
||||||
});
|
});
|
||||||
|
|
||||||
// add client count total values to the right
|
// client count total values to the right
|
||||||
chartSvg
|
let totalValueGroup = chartSvg
|
||||||
.append('g')
|
.append('g')
|
||||||
.attr('transform', `translate(${TRANSLATE.left}, ${TRANSLATE.down})`)
|
.attr('data-test-group', 'total-values')
|
||||||
|
.attr('transform', `translate(${TRANSLATE.left}, ${TRANSLATE.down})`);
|
||||||
|
|
||||||
|
totalValueGroup
|
||||||
.selectAll('text')
|
.selectAll('text')
|
||||||
.data(dataset)
|
.data(dataset)
|
||||||
.enter()
|
.enter()
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import { formatISO, isBefore, sub } from 'date-fns';
|
||||||
|
|
||||||
export default function (server) {
|
export default function (server) {
|
||||||
// 1.10 API response
|
// 1.10 API response
|
||||||
server.get('sys/version-history', function () {
|
server.get('sys/version-history', function () {
|
||||||
|
@ -88,6 +90,8 @@ export default function (server) {
|
||||||
|
|
||||||
server.get('/sys/internal/counters/activity', (schema, req) => {
|
server.get('/sys/internal/counters/activity', (schema, req) => {
|
||||||
const { start_time, end_time } = req.queryParams;
|
const { start_time, end_time } = req.queryParams;
|
||||||
|
// fake client counting start date so warning shows if user queries earlier start date
|
||||||
|
const counts_start = '2020-10-17T00:00:00Z';
|
||||||
return {
|
return {
|
||||||
request_id: '25f55fbb-f253-9c46-c6f0-3cdd3ada91ab',
|
request_id: '25f55fbb-f253-9c46-c6f0-3cdd3ada91ab',
|
||||||
lease_id: '',
|
lease_id: '',
|
||||||
|
@ -182,9 +186,9 @@ export default function (server) {
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
end_time: end_time || '2022-01-31T23:59:59Z',
|
end_time: end_time || formatISO(sub(new Date(), { months: 1 })),
|
||||||
months: [],
|
months: [],
|
||||||
start_time,
|
start_time: isBefore(new Date(start_time), new Date(counts_start)) ? counts_start : start_time,
|
||||||
total: {
|
total: {
|
||||||
distinct_entities: 37389,
|
distinct_entities: 37389,
|
||||||
entity_clients: 37389,
|
entity_clients: 37389,
|
||||||
|
|
|
@ -1,4 +1,13 @@
|
||||||
import { click, findAll, fillIn, settled, visit, triggerKeyEvent } from '@ember/test-helpers';
|
import {
|
||||||
|
click,
|
||||||
|
findAll,
|
||||||
|
fillIn,
|
||||||
|
settled,
|
||||||
|
visit,
|
||||||
|
triggerKeyEvent,
|
||||||
|
find,
|
||||||
|
waitUntil,
|
||||||
|
} from '@ember/test-helpers';
|
||||||
import { module, test } from 'qunit';
|
import { module, test } from 'qunit';
|
||||||
import { setupApplicationTest } from 'ember-qunit';
|
import { setupApplicationTest } from 'ember-qunit';
|
||||||
import authPage from 'vault/tests/pages/auth';
|
import authPage from 'vault/tests/pages/auth';
|
||||||
|
@ -31,7 +40,7 @@ module('Acceptance | auth backend list', function (hooks) {
|
||||||
await click('[data-test-save-config="true"]');
|
await click('[data-test-save-config="true"]');
|
||||||
|
|
||||||
await visit(`/vault/access/${path1}/item/user/create`);
|
await visit(`/vault/access/${path1}/item/user/create`);
|
||||||
|
await waitUntil(() => find('[data-test-input="username"]') && find('[data-test-textarea]'));
|
||||||
await fillIn('[data-test-input="username"]', user1);
|
await fillIn('[data-test-input="username"]', user1);
|
||||||
await triggerKeyEvent('[data-test-input="username"]', 'keyup', 65);
|
await triggerKeyEvent('[data-test-input="username"]', 'keyup', 65);
|
||||||
await fillIn('[data-test-textarea]', user1);
|
await fillIn('[data-test-textarea]', user1);
|
||||||
|
|
|
@ -7,6 +7,7 @@ import { create } from 'ember-cli-page-object';
|
||||||
import { clickTrigger } from 'ember-power-select/test-support/helpers';
|
import { clickTrigger } from 'ember-power-select/test-support/helpers';
|
||||||
import ss from 'vault/tests/pages/components/search-select';
|
import ss from 'vault/tests/pages/components/search-select';
|
||||||
import {
|
import {
|
||||||
|
CHART_ELEMENTS,
|
||||||
generateConfigResponse,
|
generateConfigResponse,
|
||||||
generateCurrentMonthResponse,
|
generateCurrentMonthResponse,
|
||||||
SELECTORS,
|
SELECTORS,
|
||||||
|
@ -78,7 +79,7 @@ module('Acceptance | clients current', function (hooks) {
|
||||||
assert.dom(SELECTORS.activeTab).hasText('Current month', 'current month tab is active');
|
assert.dom(SELECTORS.activeTab).hasText('Current month', 'current month tab is active');
|
||||||
assert.dom(SELECTORS.usageStats).exists('usage stats block exists');
|
assert.dom(SELECTORS.usageStats).exists('usage stats block exists');
|
||||||
assert.dom('[data-test-stat-text-container]').exists({ count: 3 }, '3 stat texts exist');
|
assert.dom('[data-test-stat-text-container]').exists({ count: 3 }, '3 stat texts exist');
|
||||||
const { clients, entity_clients, non_entity_clients } = monthly.data;
|
const { clients, entity_clients, non_entity_clients, by_namespace } = monthly.data;
|
||||||
assert.dom('[data-test-stat-text="total-clients"] .stat-value').hasText(clients.toString());
|
assert.dom('[data-test-stat-text="total-clients"] .stat-value').hasText(clients.toString());
|
||||||
assert.dom('[data-test-stat-text="entity-clients"] .stat-value').hasText(entity_clients.toString());
|
assert.dom('[data-test-stat-text="entity-clients"] .stat-value').hasText(entity_clients.toString());
|
||||||
assert
|
assert
|
||||||
|
@ -87,7 +88,28 @@ module('Acceptance | clients current', function (hooks) {
|
||||||
assert.dom('[data-test-clients-attribution]').exists('Shows attribution area');
|
assert.dom('[data-test-clients-attribution]').exists('Shows attribution area');
|
||||||
assert.dom('[data-test-horizontal-bar-chart]').exists('Shows attribution bar chart');
|
assert.dom('[data-test-horizontal-bar-chart]').exists('Shows attribution bar chart');
|
||||||
assert.dom('[data-test-top-attribution]').includesText('Top namespace');
|
assert.dom('[data-test-top-attribution]').includesText('Top namespace');
|
||||||
// Filter by namespace
|
|
||||||
|
// check chart displays correct elements and values
|
||||||
|
for (const key in CHART_ELEMENTS) {
|
||||||
|
let namespaceNumber = by_namespace.length < 10 ? by_namespace.length : 10;
|
||||||
|
let group = find(CHART_ELEMENTS[key]);
|
||||||
|
let elementArray = Array.from(group.children);
|
||||||
|
assert.equal(elementArray.length, namespaceNumber, `renders correct number of ${key}`);
|
||||||
|
if (key === 'totalValues') {
|
||||||
|
elementArray.forEach((element, i) => {
|
||||||
|
assert.equal(element.innerHTML, `${by_namespace[i].counts.clients}`, 'displays correct value');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (key === 'yLabels') {
|
||||||
|
elementArray.forEach((element, i) => {
|
||||||
|
assert
|
||||||
|
.dom(element.children[1])
|
||||||
|
.hasTextContaining(`${by_namespace[i].namespace_path}`, 'displays correct namespace label');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILTER BY NAMESPACE
|
||||||
await clickTrigger();
|
await clickTrigger();
|
||||||
await searchSelect.options.objectAt(0).click();
|
await searchSelect.options.objectAt(0).click();
|
||||||
await waitUntil(() => {
|
await waitUntil(() => {
|
||||||
|
@ -98,7 +120,29 @@ module('Acceptance | clients current', function (hooks) {
|
||||||
assert.dom('[data-test-stat-text="non-entity-clients"] .stat-value').hasText('10');
|
assert.dom('[data-test-stat-text="non-entity-clients"] .stat-value').hasText('10');
|
||||||
assert.dom('[data-test-horizontal-bar-chart]').exists('Still shows attribution bar chart');
|
assert.dom('[data-test-horizontal-bar-chart]').exists('Still shows attribution bar chart');
|
||||||
assert.dom('[data-test-top-attribution]').includesText('Top auth method');
|
assert.dom('[data-test-top-attribution]').includesText('Top auth method');
|
||||||
// Filter by auth method
|
|
||||||
|
// check chart displays correct elements and values
|
||||||
|
for (const key in CHART_ELEMENTS) {
|
||||||
|
const { mounts } = by_namespace[0];
|
||||||
|
let mountNumber = mounts.length < 10 ? mounts.length : 10;
|
||||||
|
let group = find(CHART_ELEMENTS[key]);
|
||||||
|
let elementArray = Array.from(group.children);
|
||||||
|
assert.equal(elementArray.length, mountNumber, `renders correct number of ${key}`);
|
||||||
|
if (key === 'totalValues') {
|
||||||
|
elementArray.forEach((element, i) => {
|
||||||
|
assert.equal(element.innerHTML, `${mounts[i].counts.clients}`, 'displays correct value');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (key === 'yLabels') {
|
||||||
|
elementArray.forEach((element, i) => {
|
||||||
|
assert
|
||||||
|
.dom(element.children[1])
|
||||||
|
.hasTextContaining(`${mounts[i].mount_path}`, 'displays correct auth label');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILTER BY AUTH METHOD
|
||||||
await clickTrigger();
|
await clickTrigger();
|
||||||
await searchSelect.options.objectAt(0).click();
|
await searchSelect.options.objectAt(0).click();
|
||||||
await waitUntil(() => {
|
await waitUntil(() => {
|
||||||
|
|
|
@ -8,6 +8,7 @@ import { create } from 'ember-cli-page-object';
|
||||||
import { clickTrigger } from 'ember-power-select/test-support/helpers';
|
import { clickTrigger } from 'ember-power-select/test-support/helpers';
|
||||||
import ss from 'vault/tests/pages/components/search-select';
|
import ss from 'vault/tests/pages/components/search-select';
|
||||||
import {
|
import {
|
||||||
|
CHART_ELEMENTS,
|
||||||
generateActivityResponse,
|
generateActivityResponse,
|
||||||
generateConfigResponse,
|
generateConfigResponse,
|
||||||
generateLicenseResponse,
|
generateLicenseResponse,
|
||||||
|
@ -127,6 +128,7 @@ module('Acceptance | clients history tab', function (hooks) {
|
||||||
'Date range shows dates correctly parsed activity response'
|
'Date range shows dates correctly parsed activity response'
|
||||||
);
|
);
|
||||||
assert.dom('[data-test-stat-text-container]').exists({ count: 3 }, '3 stat texts exist');
|
assert.dom('[data-test-stat-text-container]').exists({ count: 3 }, '3 stat texts exist');
|
||||||
|
const { by_namespace } = activity.data;
|
||||||
const { clients, entity_clients, non_entity_clients } = activity.data.total;
|
const { clients, entity_clients, non_entity_clients } = activity.data.total;
|
||||||
assert
|
assert
|
||||||
.dom('[data-test-stat-text="total-clients"] .stat-value')
|
.dom('[data-test-stat-text="total-clients"] .stat-value')
|
||||||
|
@ -140,6 +142,26 @@ module('Acceptance | clients history tab', function (hooks) {
|
||||||
assert.dom('[data-test-clients-attribution]').exists('Shows attribution area');
|
assert.dom('[data-test-clients-attribution]').exists('Shows attribution area');
|
||||||
assert.dom('[data-test-horizontal-bar-chart]').exists('Shows attribution bar chart');
|
assert.dom('[data-test-horizontal-bar-chart]').exists('Shows attribution bar chart');
|
||||||
assert.dom('[data-test-top-attribution]').includesText('Top namespace');
|
assert.dom('[data-test-top-attribution]').includesText('Top namespace');
|
||||||
|
|
||||||
|
// check chart displays correct elements and values
|
||||||
|
for (const key in CHART_ELEMENTS) {
|
||||||
|
let namespaceNumber = by_namespace.length < 10 ? by_namespace.length : 10;
|
||||||
|
let group = find(CHART_ELEMENTS[key]);
|
||||||
|
let elementArray = Array.from(group.children);
|
||||||
|
assert.equal(elementArray.length, namespaceNumber, `renders correct number of ${key}`);
|
||||||
|
if (key === 'totalValues') {
|
||||||
|
elementArray.forEach((element, i) => {
|
||||||
|
assert.equal(element.innerHTML, `${by_namespace[i].counts.clients}`, 'displays correct value');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (key === 'yLabels') {
|
||||||
|
elementArray.forEach((element, i) => {
|
||||||
|
assert
|
||||||
|
.dom(element.children[1])
|
||||||
|
.hasTextContaining(`${by_namespace[i].namespace_path}`, 'displays correct namespace label');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
test('filters correctly on history with full data', async function (assert) {
|
test('filters correctly on history with full data', async function (assert) {
|
||||||
|
@ -164,8 +186,9 @@ module('Acceptance | clients history tab', function (hooks) {
|
||||||
assert.dom(SELECTORS.activeTab).hasText('History', 'history tab is active');
|
assert.dom(SELECTORS.activeTab).hasText('History', 'history tab is active');
|
||||||
assert.dom(SELECTORS.usageStats).exists('usage stats block exists');
|
assert.dom(SELECTORS.usageStats).exists('usage stats block exists');
|
||||||
assert.dom('[data-test-stat-text-container]').exists({ count: 3 }, '3 stat texts exist');
|
assert.dom('[data-test-stat-text-container]').exists({ count: 3 }, '3 stat texts exist');
|
||||||
const { clients } = activity.data.total;
|
const { total, by_namespace } = activity.data;
|
||||||
// Filter by namespace
|
|
||||||
|
// FILTER BY NAMESPACE
|
||||||
await clickTrigger();
|
await clickTrigger();
|
||||||
await searchSelect.options.objectAt(0).click();
|
await searchSelect.options.objectAt(0).click();
|
||||||
await waitUntil(() => {
|
await waitUntil(() => {
|
||||||
|
@ -177,7 +200,29 @@ module('Acceptance | clients history tab', function (hooks) {
|
||||||
assert.dom('[data-test-stat-text="non-entity-clients"] .stat-value').hasText('10');
|
assert.dom('[data-test-stat-text="non-entity-clients"] .stat-value').hasText('10');
|
||||||
assert.dom('[data-test-horizontal-bar-chart]').exists('Shows attribution bar chart');
|
assert.dom('[data-test-horizontal-bar-chart]').exists('Shows attribution bar chart');
|
||||||
assert.dom('[data-test-top-attribution]').includesText('Top auth method');
|
assert.dom('[data-test-top-attribution]').includesText('Top auth method');
|
||||||
// Filter by auth method
|
|
||||||
|
// check chart displays correct elements and values
|
||||||
|
for (const key in CHART_ELEMENTS) {
|
||||||
|
const { mounts } = by_namespace[0];
|
||||||
|
let mountNumber = mounts.length < 10 ? mounts.length : 10;
|
||||||
|
let group = find(CHART_ELEMENTS[key]);
|
||||||
|
let elementArray = Array.from(group.children);
|
||||||
|
assert.equal(elementArray.length, mountNumber, `renders correct number of ${key}`);
|
||||||
|
if (key === 'totalValues') {
|
||||||
|
elementArray.forEach((element, i) => {
|
||||||
|
assert.equal(element.innerHTML, `${mounts[i].counts.clients}`, 'displays correct value');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (key === 'yLabels') {
|
||||||
|
elementArray.forEach((element, i) => {
|
||||||
|
assert
|
||||||
|
.dom(element.children[1])
|
||||||
|
.hasTextContaining(`${mounts[i].mount_path}`, 'displays correct auth label');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILTER BY AUTH METHOD
|
||||||
await clickTrigger();
|
await clickTrigger();
|
||||||
await searchSelect.options.objectAt(0).click();
|
await searchSelect.options.objectAt(0).click();
|
||||||
await settled();
|
await settled();
|
||||||
|
@ -192,7 +237,7 @@ module('Acceptance | clients history tab', function (hooks) {
|
||||||
assert.dom('[data-test-top-attribution]').includesText('Top namespace');
|
assert.dom('[data-test-top-attribution]').includesText('Top namespace');
|
||||||
assert
|
assert
|
||||||
.dom('[data-test-stat-text="total-clients"] .stat-value')
|
.dom('[data-test-stat-text="total-clients"] .stat-value')
|
||||||
.hasText(clients.toString(), 'total clients stat is back to unfiltered value');
|
.hasText(total.clients.toString(), 'total clients stat is back to unfiltered value');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('shows warning if upgrade happened within license period', async function (assert) {
|
test('shows warning if upgrade happened within license period', async function (assert) {
|
||||||
|
@ -292,7 +337,7 @@ module('Acceptance | clients history tab', function (hooks) {
|
||||||
assert.equal(currentURL(), '/vault/clients/history', 'clients/history URL is correct');
|
assert.equal(currentURL(), '/vault/clients/history', 'clients/history URL is correct');
|
||||||
assert
|
assert
|
||||||
.dom(SELECTORS.emptyStateTitle)
|
.dom(SELECTORS.emptyStateTitle)
|
||||||
.includesText('No start date found', 'Empty state shows no billing start date');
|
.includesText('start date found', 'Empty state shows no billing start date');
|
||||||
await click(SELECTORS.monthDropdown);
|
await click(SELECTORS.monthDropdown);
|
||||||
await click(this.element.querySelector('[data-test-month-list] button:not([disabled])'));
|
await click(this.element.querySelector('[data-test-month-list] button:not([disabled])'));
|
||||||
await click(SELECTORS.yearDropdown);
|
await click(SELECTORS.yearDropdown);
|
||||||
|
|
|
@ -27,6 +27,15 @@ export const SELECTORS = {
|
||||||
dateDropdownSubmit: '[data-test-date-dropdown-submit]',
|
dateDropdownSubmit: '[data-test-date-dropdown-submit]',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const CHART_ELEMENTS = {
|
||||||
|
entityClientDataBars: '[data-test-group="entity_clients"]',
|
||||||
|
nonEntityDataBars: '[data-test-group="non_entity_clients"]',
|
||||||
|
yLabels: '[data-test-group="y-labels"]',
|
||||||
|
actionBars: '[data-test-group="action-bars"]',
|
||||||
|
labelActionBars: '[data-test-group="label-action-bars"]',
|
||||||
|
totalValues: '[data-test-group="total-values"]',
|
||||||
|
};
|
||||||
|
|
||||||
export function sendResponse(data, httpStatus = 200) {
|
export function sendResponse(data, httpStatus = 200) {
|
||||||
if (httpStatus === 403) {
|
if (httpStatus === 403) {
|
||||||
return [
|
return [
|
||||||
|
@ -60,7 +69,7 @@ function generateNamespaceBlock(idx = 0, skipMounts = false) {
|
||||||
let mountCount = 1;
|
let mountCount = 1;
|
||||||
const nsBlock = {
|
const nsBlock = {
|
||||||
namespace_id: `${idx}UUID`,
|
namespace_id: `${idx}UUID`,
|
||||||
namespace_path: `my-namespace-${idx}/`,
|
namespace_path: `${idx}/namespace`,
|
||||||
counts: {
|
counts: {
|
||||||
clients: mountCount * 15,
|
clients: mountCount * 15,
|
||||||
entity_clients: mountCount * 5,
|
entity_clients: mountCount * 5,
|
||||||
|
|
Loading…
Reference in New Issue